diff options
| author | Wolfgang Denk <wd@denx.de> | 2010-09-28 23:30:47 +0200 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2010-09-28 23:30:47 +0200 | 
| commit | 2e6e1772c0e34871769be4aef79748fe3e47d953 (patch) | |
| tree | 00e4e19d7bccd2a1cd5753854ff4c2b8a26bebb0 /arch/arm/lib/board.c | |
| parent | 1e4e5ef0469050f014aee1204dae8a9ab6053e49 (diff) | |
| parent | 3df61957938586c512c17e72d83551d190400981 (diff) | |
| download | olio-uboot-2014.01-2e6e1772c0e34871769be4aef79748fe3e47d953.tar.xz olio-uboot-2014.01-2e6e1772c0e34871769be4aef79748fe3e47d953.zip | |
Merge branch 'next' of /home/wd/git/u-boot/next
Conflicts:
	include/ppc4xx.h
Signed-off-by: Wolfgang Denk <wd@denx.de>
Diffstat (limited to 'arch/arm/lib/board.c')
| -rw-r--r-- | arch/arm/lib/board.c | 468 | 
1 files changed, 467 insertions, 1 deletions
| diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index e17f182e1..5f2dfd08a 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -126,7 +126,12 @@ static int init_baudrate (void)  {  	char tmp[64];	/* long enough for environment variables */  	int i = getenv_f("baudrate", tmp, sizeof (tmp)); + +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +	gd->baudrate = (i > 0) +#else  	gd->bd->bi_baudrate = gd->baudrate = (i > 0) +#endif  			? (int) simple_strtoul (tmp, NULL, 10)  			: CONFIG_BAUDRATE; @@ -137,7 +142,12 @@ static int display_banner (void)  {  	printf ("\n\n%s\n\n", version_string);  	debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n", -	       _armboot_start, _bss_start, _bss_end); +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +	       _TEXT_BASE, +#else +	       _armboot_start, +#endif +	       _bss_start, _bss_end);  #ifdef CONFIG_MODEM_SUPPORT  	debug ("Modem Support enabled\n");  #endif @@ -180,6 +190,7 @@ static int display_dram_config (void)  	return (0);  } +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)  #ifndef CONFIG_SYS_NO_FLASH  static void display_flash_config (ulong size)  { @@ -187,6 +198,7 @@ static void display_flash_config (ulong size)  	print_size (size, "\n");  }  #endif /* CONFIG_SYS_NO_FLASH */ +#endif  #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)  static int init_func_i2c (void) @@ -234,6 +246,7 @@ typedef int (init_fnc_t) (void);  int print_cpuinfo (void); +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)  init_fnc_t *init_sequence[] = {  #if defined(CONFIG_ARCH_CPU_INIT)  	arch_cpu_init,		/* basic arch cpu dependent setup */ @@ -449,6 +462,459 @@ extern void davinci_eth_set_mac_addr (const u_int8_t *addr);  	/* NOTREACHED - no way out of command loop except booting */  } +#else +void __dram_init_banksize(void) +{ +	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; +	gd->bd->bi_dram[0].size =  gd->ram_size; +} +void dram_init_banksize(void) +	__attribute__((weak, alias("__dram_init_banksize"))); + +init_fnc_t *init_sequence[] = { +#if defined(CONFIG_ARCH_CPU_INIT) +	arch_cpu_init,		/* basic arch cpu dependent setup */ +#endif +#if defined(CONFIG_BOARD_EARLY_INIT_F) +	board_early_init_f, +#endif +	timer_init,		/* initialize timer */ +#ifdef CONFIG_FSL_ESDHC +	get_clocks, +#endif +	env_init,		/* initialize environment */ +	init_baudrate,		/* initialze baudrate settings */ +	serial_init,		/* serial communications setup */ +	console_init_f,		/* stage 1 init of console */ +	display_banner,		/* say that we are here */ +#if defined(CONFIG_DISPLAY_CPUINFO) +	print_cpuinfo,		/* display cpu info (and speed) */ +#endif +#if defined(CONFIG_DISPLAY_BOARDINFO) +	checkboard,		/* display board info */ +#endif +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) +	init_func_i2c, +#endif +	dram_init,		/* configure available RAM banks */ +#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) +	arm_pci_init, +#endif +	NULL, +}; + +void board_init_f (ulong bootflag) +{ +	bd_t *bd; +	init_fnc_t **init_fnc_ptr; +	gd_t *id; +	ulong addr, addr_sp; + +	/* Pointer is writable since we allocated a register for it */ +	gd = (gd_t *) (CONFIG_SYS_INIT_SP_ADDR); +	/* compiler optimization barrier needed for GCC >= 3.4 */ +	__asm__ __volatile__("": : :"memory"); + +	memset ((void*)gd, 0, sizeof (gd_t)); + +	gd->mon_len = _bss_end - _TEXT_BASE; + +	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { +		if ((*init_fnc_ptr)() != 0) { +			hang (); +		} +	} + +	debug ("monitor len: %08lX\n", gd->mon_len); +	/* +	 * Ram is setup, size stored in gd !! +	 */ +	debug ("ramsize: %08lX\n", gd->ram_size); +#if defined(CONFIG_SYS_MEM_TOP_HIDE) +	/* +	 * Subtract specified amount of memory to hide so that it won't +	 * get "touched" at all by U-Boot. By fixing up gd->ram_size +	 * the Linux kernel should now get passed the now "corrected" +	 * memory size and won't touch it either. This should work +	 * for arch/ppc and arch/powerpc. Only Linux board ports in +	 * arch/powerpc with bootwrapper support, that recalculate the +	 * memory size from the SDRAM controller setup will have to +	 * get fixed. +	 */ +	gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; +#endif + +	addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; + +#ifdef CONFIG_LOGBUFFER +#ifndef CONFIG_ALT_LB_ADDR +	/* reserve kernel log buffer */ +	addr -= (LOGBUFF_RESERVE); +	debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr); +#endif +#endif + +#ifdef CONFIG_PRAM +	/* +	 * reserve protected RAM +	 */ +	i = getenv_r ("pram", (char *)tmp, sizeof (tmp)); +	reg = (i > 0) ? simple_strtoul ((const char *)tmp, NULL, 10) : CONFIG_PRAM; +	addr -= (reg << 10);		/* size is in kB */ +	debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr); +#endif /* CONFIG_PRAM */ + +#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) +	/* reserve TLB table */ +	addr -= (4096 * 4); + +	/* round down to next 64 kB limit */ +	addr &= ~(0x10000 - 1); + +	gd->tlb_addr = addr; +	debug ("TLB table at: %08lx\n", addr); +#endif + +	/* round down to next 4 kB limit */ +	addr &= ~(4096 - 1); +	debug ("Top of RAM usable for U-Boot at: %08lx\n", addr); + +#ifdef CONFIG_VFD +#	ifndef PAGE_SIZE +#	  define PAGE_SIZE 4096 +#	endif +	/* +	 * reserve memory for VFD display (always full pages) +	 */ +	addr -= vfd_setmem (addr); +	gd->fb_base = addr; +#endif /* CONFIG_VFD */ + +#ifdef CONFIG_LCD +	/* reserve memory for LCD display (always full pages) */ +	addr = lcd_setmem (addr); +	gd->fb_base = addr; +#endif /* CONFIG_LCD */ + +	/* +	 * reserve memory for U-Boot code, data & bss +	 * round down to next 4 kB limit +	 */ +	addr -= gd->mon_len; +	addr &= ~(4096 - 1); + +	debug ("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr); + +#ifndef CONFIG_PRELOADER +	/* +	 * reserve memory for malloc() arena +	 */ +	addr_sp = addr - TOTAL_MALLOC_LEN; +	debug ("Reserving %dk for malloc() at: %08lx\n", +			TOTAL_MALLOC_LEN >> 10, addr_sp); +	/* +	 * (permanently) allocate a Board Info struct +	 * and a permanent copy of the "global" data +	 */ +	addr_sp -= sizeof (bd_t); +	bd = (bd_t *) addr_sp; +	gd->bd = bd; +	debug ("Reserving %zu Bytes for Board Info at: %08lx\n", +			sizeof (bd_t), addr_sp); +	addr_sp -= sizeof (gd_t); +	id = (gd_t *) addr_sp; +	debug ("Reserving %zu Bytes for Global Data at: %08lx\n", +			sizeof (gd_t), addr_sp); + +	/* setup stackpointer for exeptions */ +	gd->irq_sp = addr_sp; +#ifdef CONFIG_USE_IRQ +	addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ); +	debug ("Reserving %zu Bytes for IRQ stack at: %08lx\n", +		CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp); +#endif +	/* leave 3 words for abort-stack    */ +	addr_sp -= 3; + +	/* 8-byte alignment for ABI compliance */ +	addr_sp &= ~0x07; +#else +	addr_sp += 128;	/* leave 32 words for abort-stack   */ +	gd->irq_sp = addr_sp; +#endif + +	debug ("New Stack Pointer is: %08lx\n", addr_sp); + +#ifdef CONFIG_POST +	post_bootmode_init(); +	post_run (NULL, POST_ROM | post_bootmode_get(0)); +#endif + +	gd->bd->bi_baudrate = gd->baudrate; +	/* Ram ist board specific, so move it to board code ... */ +	dram_init_banksize(); +	display_dram_config();	/* and display it */ + +	gd->relocaddr = addr; +	gd->start_addr_sp = addr_sp; +	gd->reloc_off = addr - _TEXT_BASE; +	debug ("relocation Offset is: %08lx\n", gd->reloc_off); +	memcpy (id, (void *)gd, sizeof (gd_t)); + +	relocate_code (addr_sp, id, addr); + +	/* NOTREACHED - relocate_code() does not return */ +} + +#if !defined(CONFIG_SYS_NO_FLASH) +static char *failed = "*** failed ***\n"; +#endif + +/************************************************************************ + * + * This is the next part if the initialization sequence: we are now + * running from RAM and have a "normal" C environment, i. e. global + * data can be written, BSS has been cleared, the stack size in not + * that critical any more, etc. + * + ************************************************************************ + */ +void board_init_r (gd_t *id, ulong dest_addr) +{ +	char *s; +	bd_t *bd; +	ulong malloc_start; +#if !defined(CONFIG_SYS_NO_FLASH) +	ulong flash_size; +#endif +#if !defined(CONFIG_RELOC_FIXUP_WORKS) +	extern void malloc_bin_reloc (void); +#if defined(CONFIG_CMD_BMP) +	extern void bmp_reloc(void); +#endif +#if defined(CONFIG_CMD_I2C) +	extern void i2c_reloc(void); +#endif +#endif + +	gd = id; +	bd = gd->bd; + +	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */ + +	monitor_flash_len = _bss_start - _TEXT_BASE; +	debug ("monitor flash len: %08lX\n", monitor_flash_len); +	board_init();	/* Setup chipselects */ + +#ifdef CONFIG_SERIAL_MULTI +	serial_initialize(); +#endif + +	debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr); + +#if !defined(CONFIG_RELOC_FIXUP_WORKS) +	/* +	 * We have to relocate the command table manually +	 */ +	fixup_cmdtable(&__u_boot_cmd_start, +		(ulong)(&__u_boot_cmd_end - &__u_boot_cmd_start)); +#if defined(CONFIG_CMD_BMP) +	bmp_reloc(); +#endif +#if defined(CONFIG_CMD_I2C) +	i2c_reloc(); +#endif +#endif /* !defined(CONFIG_RELOC_FIXUP_WORKS) */ + +#ifdef CONFIG_LOGBUFFER +	logbuff_init_ptrs (); +#endif +#ifdef CONFIG_POST +	post_output_backlog (); +#ifndef CONFIG_RELOC_FIXUP_WORKS +	post_reloc (); +#endif +#endif + +	/* The Malloc area is immediately below the monitor copy in DRAM */ +	malloc_start = dest_addr - TOTAL_MALLOC_LEN; +	mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); +#if !defined(CONFIG_RELOC_FIXUP_WORKS) +	malloc_bin_reloc (); +#endif + +#if !defined(CONFIG_SYS_NO_FLASH) +	puts ("FLASH: "); + +	if ((flash_size = flash_init ()) > 0) { +# ifdef CONFIG_SYS_FLASH_CHECKSUM +		print_size (flash_size, ""); +		/* +		 * Compute and print flash CRC if flashchecksum is set to 'y' +		 * +		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX +		 */ +		s = getenv ("flashchecksum"); +		if (s && (*s == 'y')) { +			printf ("  CRC: %08X", +				crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size) +			); +		} +		putc ('\n'); +# else	/* !CONFIG_SYS_FLASH_CHECKSUM */ +		print_size (flash_size, "\n"); +# endif /* CONFIG_SYS_FLASH_CHECKSUM */ +	} else { +		puts (failed); +		hang (); +	} +#endif + +#if defined(CONFIG_CMD_NAND) +	puts ("NAND:  "); +	nand_init();		/* go init the NAND */ +#endif + +#if defined(CONFIG_CMD_ONENAND) +	onenand_init(); +#endif + +#ifdef CONFIG_HAS_DATAFLASH +	AT91F_DataflashInit(); +	dataflash_print_info(); +#endif + +	/* initialize environment */ +	env_relocate (); + +#ifdef CONFIG_VFD +	/* must do this after the framebuffer is allocated */ +	drv_vfd_init(); +#endif /* CONFIG_VFD */ + +	/* IP Address */ +	gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); + +	stdio_init ();	/* get the devices list going. */ + +	jumptable_init (); + +#if defined(CONFIG_API) +	/* Initialize API */ +	api_init (); +#endif + +	console_init_r ();	/* fully init console as a device */ + +#if defined(CONFIG_ARCH_MISC_INIT) +	/* miscellaneous arch dependent initialisations */ +	arch_misc_init (); +#endif +#if defined(CONFIG_MISC_INIT_R) +	/* miscellaneous platform dependent initialisations */ +	misc_init_r (); +#endif + +	 /* set up exceptions */ +	interrupt_init (); +	/* enable exceptions */ +	enable_interrupts (); + +	/* Perform network card initialisation if necessary */ +#ifdef CONFIG_DRIVER_TI_EMAC +	/* XXX: this needs to be moved to board init */ +extern void davinci_eth_set_mac_addr (const u_int8_t *addr); +	if (getenv ("ethaddr")) { +		uchar enetaddr[6]; +		eth_getenv_enetaddr("ethaddr", enetaddr); +		davinci_eth_set_mac_addr(enetaddr); +	} +#endif + +#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96) +	/* XXX: this needs to be moved to board init */ +	if (getenv ("ethaddr")) { +		uchar enetaddr[6]; +		eth_getenv_enetaddr("ethaddr", enetaddr); +		smc_set_mac_addr(enetaddr); +	} +#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ + +	/* Initialize from environment */ +	if ((s = getenv ("loadaddr")) != NULL) { +		load_addr = simple_strtoul (s, NULL, 16); +	} +#if defined(CONFIG_CMD_NET) +	if ((s = getenv ("bootfile")) != NULL) { +		copy_filename (BootFile, s, sizeof (BootFile)); +	} +#endif + +#ifdef BOARD_LATE_INIT +	board_late_init (); +#endif + +#ifdef CONFIG_GENERIC_MMC +	puts ("MMC:   "); +	mmc_initialize (gd->bd); +#endif + +#ifdef CONFIG_BITBANGMII +	bb_miiphy_init(); +#endif +#if defined(CONFIG_CMD_NET) +#if defined(CONFIG_NET_MULTI) +	puts ("Net:   "); +#endif +	eth_initialize(gd->bd); +#if defined(CONFIG_RESET_PHY_R) +	debug ("Reset Ethernet PHY\n"); +	reset_phy(); +#endif +#endif + +#ifdef CONFIG_POST +	post_run (NULL, POST_RAM | post_bootmode_get(0)); +#endif + +#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) +	/* +	 * Export available size of memory for Linux, +	 * taking into account the protected RAM at top of memory +	 */ +	{ +		ulong pram; +		uchar memsz[32]; +#ifdef CONFIG_PRAM +		char *s; + +		if ((s = getenv ("pram")) != NULL) { +			pram = simple_strtoul (s, NULL, 10); +		} else { +			pram = CONFIG_PRAM; +		} +#else +		pram=0; +#endif +#ifdef CONFIG_LOGBUFFER +#ifndef CONFIG_ALT_LB_ADDR +		/* Also take the logbuffer into account (pram is in kB) */ +		pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024; +#endif +#endif +		sprintf ((char *)memsz, "%ldk", (bd->bi_memsize / 1024) - pram); +		setenv ("mem", (char *)memsz); +	} +#endif + +	/* main_loop() can return to retry autoboot, if so just run it again. */ +	for (;;) { +		main_loop (); +	} + +	/* NOTREACHED - no way out of command loop except booting */ +} +#endif /* defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */  void hang (void)  { |