diff options
Diffstat (limited to 'arch/nios2/cpu')
| -rw-r--r-- | arch/nios2/cpu/Makefile | 2 | ||||
| -rw-r--r-- | arch/nios2/cpu/cpu.c | 128 | ||||
| -rw-r--r-- | arch/nios2/cpu/interrupts.c | 144 | ||||
| -rw-r--r-- | arch/nios2/cpu/start.S | 186 | ||||
| -rw-r--r-- | arch/nios2/cpu/sysid.c | 46 | ||||
| -rw-r--r-- | arch/nios2/cpu/u-boot.lds | 14 | 
6 files changed, 193 insertions, 327 deletions
| diff --git a/arch/nios2/cpu/Makefile b/arch/nios2/cpu/Makefile index 3fe7847160d..185ca3cdb76 100644 --- a/arch/nios2/cpu/Makefile +++ b/arch/nios2/cpu/Makefile @@ -7,5 +7,5 @@  extra-y	= start.o  obj-y	= exceptions.o -obj-y	+= cpu.o interrupts.o sysid.o traps.o +obj-y	+= cpu.o interrupts.o traps.o  obj-y	+= fdt.o diff --git a/arch/nios2/cpu/cpu.c b/arch/nios2/cpu/cpu.c index 39ae97221c2..ff0fa20798f 100644 --- a/arch/nios2/cpu/cpu.c +++ b/arch/nios2/cpu/cpu.c @@ -6,25 +6,18 @@   */  #include <common.h> -#include <asm/nios2.h> +#include <cpu.h> +#include <dm.h> +#include <errno.h>  #include <asm/cache.h>  DECLARE_GLOBAL_DATA_PTR; -#if defined (CONFIG_SYS_NIOS_SYSID_BASE) -extern void display_sysid (void); -#endif /* CONFIG_SYS_NIOS_SYSID_BASE */ -  #ifdef CONFIG_DISPLAY_CPUINFO  int print_cpuinfo(void)  { -	printf ("CPU   : Nios-II\n"); -#if !defined(CONFIG_SYS_NIOS_SYSID_BASE) -	printf ("SYSID : <unknown>\n"); -#else -	display_sysid (); -#endif -	return (0); +	printf("CPU:   Nios-II\n"); +	return 0;  }  #endif /* CONFIG_DISPLAY_CPUINFO */ @@ -32,29 +25,120 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	disable_interrupts();  	/* indirect call to go beyond 256MB limitation of toolchain */ -	nios2_callr(CONFIG_SYS_RESET_ADDR); +	nios2_callr(gd->arch.reset_addr);  	return 0;  } -int dcache_status(void) +/* + * COPY EXCEPTION TRAMPOLINE -- copy the tramp to the + * exception address. Define CONFIG_ROM_STUBS to prevent + * the copy (e.g. exception in flash or in other + * softare/firmware component). + */ +#ifndef CONFIG_ROM_STUBS +static void copy_exception_trampoline(void)  { -	return 1; +	extern int _except_start, _except_end; +	void *except_target = (void *)gd->arch.exception_addr; + +	if (&_except_start != except_target) { +		memcpy(except_target, &_except_start, +		       &_except_end - &_except_start); +		flush_cache(gd->arch.exception_addr, +			    &_except_end - &_except_start); +	}  } +#endif -void dcache_enable(void) +int arch_cpu_init_dm(void)  { -	flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE); +	struct udevice *dev; +	int ret; + +	ret = uclass_first_device(UCLASS_CPU, &dev); +	if (ret) +		return ret; +	if (!dev) +		return -ENODEV; + +	gd->ram_size = CONFIG_SYS_SDRAM_SIZE; +#ifndef CONFIG_ROM_STUBS +	copy_exception_trampoline(); +#endif + +	return 0;  } -void dcache_disable(void) +static int altera_nios2_get_desc(struct udevice *dev, char *buf, int size)  { -	flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE); +	const char *cpu_name = "Nios-II"; + +	if (size < strlen(cpu_name)) +		return -ENOSPC; +	strcpy(buf, cpu_name); + +	return 0;  } -int arch_cpu_init(void) +static int altera_nios2_get_info(struct udevice *dev, struct cpu_info *info)  { -	gd->cpu_clk = CONFIG_SYS_CLK_FREQ; -	gd->ram_size = CONFIG_SYS_SDRAM_SIZE; +	info->cpu_freq = gd->cpu_clk; +	info->features = (1 << CPU_FEAT_L1_CACHE) | +		(gd->arch.has_mmu ? (1 << CPU_FEAT_MMU) : 0);  	return 0;  } + +static int altera_nios2_get_count(struct udevice *dev) +{ +	return 1; +} + +static int altera_nios2_probe(struct udevice *dev) +{ +	const void *blob = gd->fdt_blob; +	int node = dev->of_offset; + +	gd->cpu_clk = fdtdec_get_int(blob, node, +		"clock-frequency", 0); +	gd->arch.dcache_line_size = fdtdec_get_int(blob, node, +		"dcache-line-size", 0); +	gd->arch.icache_line_size = fdtdec_get_int(blob, node, +		"icache-line-size", 0); +	gd->arch.dcache_size = fdtdec_get_int(blob, node, +		"dcache-size", 0); +	gd->arch.icache_size = fdtdec_get_int(blob, node, +		"icache-size", 0); +	gd->arch.reset_addr = fdtdec_get_int(blob, node, +		"altr,reset-addr", 0); +	gd->arch.exception_addr = fdtdec_get_int(blob, node, +		"altr,exception-addr", 0); +	gd->arch.has_initda = fdtdec_get_int(blob, node, +		"altr,has-initda", 0); +	gd->arch.has_mmu = fdtdec_get_int(blob, node, +		"altr,has-mmu", 0); +	gd->arch.io_region_base = gd->arch.has_mmu ? 0xe0000000 : 0x8000000; + +	return 0; +} + +static const struct cpu_ops altera_nios2_ops = { +	.get_desc	= altera_nios2_get_desc, +	.get_info	= altera_nios2_get_info, +	.get_count	= altera_nios2_get_count, +}; + +static const struct udevice_id altera_nios2_ids[] = { +	{ .compatible = "altr,nios2-1.0" }, +	{ .compatible = "altr,nios2-1.1" }, +	{ } +}; + +U_BOOT_DRIVER(altera_nios2) = { +	.name		= "altera_nios2", +	.id		= UCLASS_CPU, +	.of_match	= altera_nios2_ids, +	.probe		= altera_nios2_probe, +	.ops		= &altera_nios2_ops, +	.flags		= DM_FLAG_PRE_RELOC, +}; diff --git a/arch/nios2/cpu/interrupts.c b/arch/nios2/cpu/interrupts.c index 9d7e193e284..1599674353c 100644 --- a/arch/nios2/cpu/interrupts.c +++ b/arch/nios2/cpu/interrupts.c @@ -8,43 +8,14 @@   * SPDX-License-Identifier:	GPL-2.0+   */ - +#include <common.h> +#include <command.h>  #include <asm/nios2.h>  #include <asm/types.h>  #include <asm/io.h>  #include <asm/ptrace.h> -#include <common.h> -#include <command.h> -#include <watchdog.h> -#ifdef CONFIG_STATUS_LED -#include <status_led.h> -#endif - -typedef volatile struct { -	unsigned	status;			/* Timer status reg */ -	unsigned	control;		/* Timer control reg */ -	unsigned	periodl;		/* Timeout period low */ -	unsigned	periodh;		/* Timeout period high */ -	unsigned	snapl;			/* Snapshot low */ -	unsigned	snaph;			/* Snapshot high */ -} nios_timer_t; - -/* status register */ -#define NIOS_TIMER_TO		(1 << 0)	/* Timeout */ -#define NIOS_TIMER_RUN		(1 << 1)	/* Timer running */ - -/* control register */ -#define NIOS_TIMER_ITO		(1 << 0)	/* Timeout int ena */ -#define NIOS_TIMER_CONT		(1 << 1)	/* Continuous mode */ -#define NIOS_TIMER_START	(1 << 2)	/* Start timer */ -#define NIOS_TIMER_STOP		(1 << 3)	/* Stop timer */ - -#if defined(CONFIG_SYS_NIOS_TMRBASE) && !defined(CONFIG_SYS_NIOS_TMRIRQ) -#error CONFIG_SYS_NIOS_TMRIRQ not defined (see documentation) -#endif - -/****************************************************************************/ +/*************************************************************************/  struct	irq_action {  	interrupt_handler_t *handler;  	void *arg; @@ -53,111 +24,6 @@ struct	irq_action {  static struct irq_action vecs[32]; -/*************************************************************************/ -volatile ulong timestamp = 0; - -void reset_timer (void) -{ -	nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; - -	/* From Embedded Peripherals Handbook: -	 * -	 * "When the hardware is configured with Writeable period -	 * disabled, writing to one of the period_n registers causes -	 * the counter to reset to the fixed Timeout Period specified -	 * at system generation time." -	 * -	 * Here we force a reload to prevent early timeouts from -	 * get_timer() when the interrupt period is greater than -	 * than 1 msec. -	 * -	 * Simply write to periodl with its own value to force an -	 * internal counter reload, THEN reset the timestamp. -	 */ -	writel (readl (&tmr->periodl), &tmr->periodl); -	timestamp = 0; - -	/* From Embedded Peripherals Handbook: -	 * -	 * "Writing to one of the period_n registers stops the internal -	 * counter, except when the hardware is configured with Start/Stop -	 * control bits off. If Start/Stop control bits is off, writing -	 * either register does not stop the counter." -	 * -	 * In order to accomodate either configuration, the control -	 * register is re-written. If the counter is stopped, it will -	 * be restarted. If it is running, the write is essentially -	 * a nop. -	 */ -	writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, -			&tmr->control); - -} - -ulong get_timer (ulong base) -{ -	WATCHDOG_RESET (); -	return (timestamp - base); -} - -/* - * This function is derived from Blackfin code (read timebase as long long). - * On Nios2 it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ -	return get_timer(0); -} - -/* - * This function is derived from Blackfin code. - * On Nios2 it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ -	ulong tbclk; - -	tbclk = CONFIG_SYS_HZ; -	return tbclk; -} - -/* The board must handle this interrupt if a timer is not - * provided. - */ -#if defined(CONFIG_SYS_NIOS_TMRBASE) -void tmr_isr (void *arg) -{ -	nios_timer_t *tmr = (nios_timer_t *)arg; -	/* Interrupt is cleared by writing anything to the -	 * status register. -	 */ -	writel (0, &tmr->status); -	timestamp += CONFIG_SYS_NIOS_TMRMS; -#ifdef CONFIG_STATUS_LED -	status_led_tick(timestamp); -#endif -} - -static void tmr_init (void) -{ -	nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; - -	writel (0, &tmr->status); -	writel (0, &tmr->control); -	writel (NIOS_TIMER_STOP, &tmr->control); - -#if defined(CONFIG_SYS_NIOS_TMRCNT) -	writel (CONFIG_SYS_NIOS_TMRCNT & 0xffff, &tmr->periodl); -	writel ((CONFIG_SYS_NIOS_TMRCNT >> 16) & 0xffff, &tmr->periodh); -#endif -	writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, -			&tmr->control); -	irq_install_handler (CONFIG_SYS_NIOS_TMRIRQ, tmr_isr, (void *)tmr); -} - -#endif /* CONFIG_SYS_NIOS_TMRBASE */ - -/*************************************************************************/  int disable_interrupts (void)  {  	int val = rdctl (CTL_STATUS); @@ -245,10 +111,6 @@ int interrupt_init (void)  		vecs[i].count = 0;  	} -#if defined(CONFIG_SYS_NIOS_TMRBASE) -	tmr_init (); -#endif -  	enable_interrupts ();  	return (0);  } diff --git a/arch/nios2/cpu/start.S b/arch/nios2/cpu/start.S index 6af9b4e9433..8758e7e847a 100644 --- a/arch/nios2/cpu/start.S +++ b/arch/nios2/cpu/start.S @@ -9,30 +9,38 @@  #include <config.h>  #include <version.h> -/************************************************************************* - * RESTART - ************************************************************************/ +/* + * icache and dcache configuration used only for start.S. + * the values are chosen so that it will work for all configuration. + */ +#define ICACHE_LINE_SIZE	32 /* fixed 32 */ +#define ICACHE_SIZE_MAX		0x10000 /* 64k max */ +#define DCACHE_LINE_SIZE_MIN	4 /* 4, 16, 32 */ +#define DCACHE_SIZE_MAX		0x10000 /* 64k max */ +	/* RESTART */  	.text -	.global _start +	.global _start, _except_start, _except_end  _start:  	wrctl	status, r0		/* Disable interrupts */ -	/* ICACHE INIT -- only the icache line at the reset address +	/* +	 * ICACHE INIT -- only the icache line at the reset address  	 * is invalidated at reset. So the init must stay within  	 * the cache line size (8 words). If GERMS is used, we'll  	 * just be invalidating the cache a second time. If cache  	 * is not implemented initi behaves as nop.  	 */ -	ori	r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE) -	movhi	r5, %hi(CONFIG_SYS_ICACHE_SIZE) -	ori	r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE) +	ori	r4, r0, %lo(ICACHE_LINE_SIZE) +	movhi	r5, %hi(ICACHE_SIZE_MAX) +	ori	r5, r5, %lo(ICACHE_SIZE_MAX)  0:	initi	r5  	sub	r5, r5, r4  	bgt	r5, r0, 0b  	br	_except_end	/* Skip the tramp */ -	/* EXCEPTION TRAMPOLINE -- the following gets copied +	/* +	 * EXCEPTION TRAMPOLINE -- the following gets copied  	 * to the exception address (below), but is otherwise at the  	 * default exception vector offset (0x0020).  	 */ @@ -42,24 +50,26 @@ _except_start:  	jmp	et  _except_end: -	/* INTERRUPTS -- for now, all interrupts masked and globally +	/* +	 * INTERRUPTS -- for now, all interrupts masked and globally  	 * disabled.  	 */  	wrctl	ienable, r0		/* All disabled	*/ -	/* DCACHE INIT -- if dcache not implemented, initd behaves as +	/* +	 * DCACHE INIT -- if dcache not implemented, initd behaves as  	 * nop.  	 */ -	movhi	r4, %hi(CONFIG_SYS_DCACHELINE_SIZE) -	ori	r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE) -	movhi	r5, %hi(CONFIG_SYS_DCACHE_SIZE) -	ori	r5, r5, %lo(CONFIG_SYS_DCACHE_SIZE) +	ori	r4, r0, %lo(DCACHE_LINE_SIZE_MIN) +	movhi	r5, %hi(DCACHE_SIZE_MAX) +	ori	r5, r5, %lo(DCACHE_SIZE_MAX)  	mov	r6, r0  1:	initd	0(r6)  	add	r6, r6, r4  	bltu	r6, r5, 1b -	/* RELOCATE CODE, DATA & COMMAND TABLE -- the following code +	/* +	 * RELOCATE CODE, DATA & COMMAND TABLE -- the following code  	 * assumes code, data and the command table are all  	 * contiguous. This lets us relocate everything as a single  	 * block. Make sure the linker script matches this ;-) @@ -73,8 +83,9 @@ _cur:	movhi	r5, %hi(_cur - _start)  	ori	r5, r5, %lo(_start)	/* r5 <- linked _start */  	beq	r4, r5, 3f -	movhi	r6, %hi(_edata) -	ori	r6, r6, %lo(_edata) +	movhi	r6, %hi(CONFIG_SYS_MONITOR_LEN) +	ori	r6, r6, %lo(CONFIG_SYS_MONITOR_LEN) +	add	r6, r6, r5  2:	ldwio	r7, 0(r4)  	addi	r4, r4, 4  	stwio	r7, 0(r5) @@ -82,50 +93,13 @@ _cur:	movhi	r5, %hi(_cur - _start)  	bne	r5, r6, 2b  3: -	/* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent -	 * and between __bss_start and __bss_end. -	 */ -	 movhi	r5, %hi(__bss_start) -	 ori	r5, r5, %lo(__bss_start) -	 movhi	r6, %hi(__bss_end) -	 ori	r6, r6, %lo(__bss_end) -	 beq	r5, r6, 5f - -4:	stwio	r0, 0(r5) -	 addi	r5, r5, 4 -	 bne	r5, r6, 4b -5: -  	/* JUMP TO RELOC ADDR */  	movhi	r4, %hi(_reloc)  	ori	r4, r4, %lo(_reloc)  	jmp	r4  _reloc: -	/* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the -	 * exception address. Define CONFIG_ROM_STUBS to prevent -	 * the copy (e.g. exception in flash or in other -	 * softare/firmware component). -	 */ -#if !defined(CONFIG_ROM_STUBS) -	movhi	r4, %hi(_except_start) -	ori	r4, r4, %lo(_except_start) -	movhi	r5, %hi(_except_end) -	ori	r5, r5, %lo(_except_end) -	movhi	r6, %hi(CONFIG_SYS_EXCEPTION_ADDR) -	ori	r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR) -	beq	r4, r6, 7f	/* Skip if at proper addr */ - -6:	ldwio	r7, 0(r4) -	stwio	r7, 0(r6) -	addi	r4, r4, 4 -	addi	r6, r6, 4 -	bne	r4, r5, 6b -7: -#endif - -	/* STACK INIT -- zero top two words for call back chain. -	 */ +	/* STACK INIT -- zero top two words for call back chain. */  	movhi	sp, %hi(CONFIG_SYS_INIT_SP)  	ori	sp, sp, %lo(CONFIG_SYS_INIT_SP)  	addi	sp, sp, -8 @@ -133,80 +107,64 @@ _reloc:  	stw	r0, 4(sp)  	mov	fp, sp -	/* -	 * Call board_init_f -- never returns -	 */ +	/* Allocate and zero GD, update SP */ +	mov	r4, sp +	movhi	r2, %hi(board_init_f_mem@h) +	ori	r2, r2, %lo(board_init_f_mem@h) +	callr	r2 + +	/* Update stack- and frame-pointers */ +	mov	sp, r2 +	mov	fp, sp + +	/* Call board_init_f -- never returns */  	mov	r4, r0  	movhi	r2, %hi(board_init_f@h)  	ori	r2, r2, %lo(board_init_f@h)  	callr	r2 -	/* NEVER RETURNS -- but branch to the _start just +	/* +	 * NEVER RETURNS -- but branch to the _start just  	 * in case ;-)  	 */  	br	_start - - -/* - * relocate_code -- Nios2 handles the relocation above. But - * the generic board code monkeys with the heap, stack, etc. - * (it makes some assumptions that may not be appropriate - * for Nios). Nevertheless, we capitulate here. - * - * We'll call the board_init_r from here since this isn't - * supposed to return. - * - * void relocate_code (ulong sp, gd_t *global_data, - *			ulong reloc_addr) - *			__attribute__ ((noreturn)); - */ +	/* +	 * relocate_code -- Nios2 handles the relocation above. But +	 * the generic board code monkeys with the heap, stack, etc. +	 * (it makes some assumptions that may not be appropriate +	 * for Nios). Nevertheless, we capitulate here. +	 * +	 * We'll call the board_init_r from here since this isn't +	 * supposed to return. +	 * +	 * void relocate_code (ulong sp, gd_t *global_data, +	 *			ulong reloc_addr) +	 *			__attribute__ ((noreturn)); +	 */  	.text  	.global relocate_code  relocate_code:  	mov	sp, r4		/* Set the new sp */  	mov	r4, r5 -	movhi	r8, %hi(board_init_r@h) -	ori	r8, r8, %lo(board_init_r@h) -	callr	r8 -	ret -/* - * dly_clks -- Nios2 (like Nios1) doesn't have a timebase in - * the core. For simple delay loops, we do our best by counting - * instruction cycles. - * - * Instruction performance varies based on the core. For cores - * with icache and static/dynamic branch prediction (II/f, II/s): - * - *	Normal ALU (e.g. add, cmp, etc):	1 cycle - *	Branch (correctly predicted, taken):	2 cycles - *	Negative offset is predicted (II/s). - * - * For cores without icache and no branch prediction (II/e): - * - *	Normal ALU (e.g. add, cmp, etc):	6 cycles - *	Branch (no prediction):			6 cycles - * - * For simplicity, if an instruction cache is implemented we - * assume II/f or II/s. Otherwise, we use the II/e. - * - */ -	.globl dly_clks +	/* +	 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent +	 * and between __bss_start and __bss_end. +	 */ +	movhi	r5, %hi(__bss_start) +	ori	r5, r5, %lo(__bss_start) +	movhi	r6, %hi(__bss_end) +	ori	r6, r6, %lo(__bss_end) +	beq	r5, r6, 5f -dly_clks: +4:	stwio	r0, 0(r5) +	addi	r5, r5, 4 +	bne	r5, r6, 4b +5: -#if (CONFIG_SYS_ICACHE_SIZE > 0) -	subi	r4, r4, 3		/* 3 clocks/loop	*/ -#else -	subi	r4, r4, 12		/* 12 clocks/loop	*/ -#endif -	bge	r4, r0, dly_clks +	movhi	r8, %hi(board_init_r@h) +	ori	r8, r8, %lo(board_init_r@h) +	callr	r8  	ret - -	.data -	.globl	version_string - -version_string: -	.ascii U_BOOT_VERSION_STRING, "\0" diff --git a/arch/nios2/cpu/sysid.c b/arch/nios2/cpu/sysid.c deleted file mode 100644 index 50819b24249..00000000000 --- a/arch/nios2/cpu/sysid.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * (C) Copyright 2004, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier:	GPL-2.0+ - */ - -#include <common.h> - -#if defined (CONFIG_SYS_NIOS_SYSID_BASE) - -#include <command.h> -#include <asm/io.h> -#include <linux/time.h> - -typedef volatile struct { -	unsigned	id;			/* The system build id */ -	unsigned	timestamp;		/* Timestamp */ -} nios_sysid_t; - -void display_sysid (void) -{ -	nios_sysid_t *sysid = (nios_sysid_t *)CONFIG_SYS_NIOS_SYSID_BASE; -	struct tm t; -	char asc[32]; -	time_t stamp; - -	stamp = readl (&sysid->timestamp); -	localtime_r (&stamp, &t); -	asctime_r (&t, asc); -	printf ("SYSID : %08lx, %s", readl (&sysid->id), asc); - -} - -int do_sysid (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ -	display_sysid (); -	return (0); -} - -U_BOOT_CMD( -	sysid,	1,	1,	do_sysid, -	"display Nios-II system id", -	"" -); -#endif /* CONFIG_SYS_NIOS_SYSID_BASE */ diff --git a/arch/nios2/cpu/u-boot.lds b/arch/nios2/cpu/u-boot.lds index 6e174be2c0c..3bd3f2c520b 100644 --- a/arch/nios2/cpu/u-boot.lds +++ b/arch/nios2/cpu/u-boot.lds @@ -50,9 +50,11 @@ SECTIONS  	  *(.gnu.linkonce.d*)  	} -	. = ALIGN(16); -	_gp = .;			/* Global pointer addr */ -	PROVIDE (gp = .); +	/* +	 * gp - Since we don't use gp for small data with option "-G0", +	 * we will use gp as global data pointer. The _gp location is +	 * not needed. +	 */  	.sdata :  	{ @@ -65,6 +67,12 @@ SECTIONS  	_edata = .;  	PROVIDE (edata = .); +	/* +	 * _end - This is end of u-boot.bin image. +	 * dtb will be appended here to make u-boot-dtb.bin +	 */ +	_end = .; +  	/* UNINIT DATA - Small uninitialized data is first so it's  	 * adjacent to sdata and can be referenced via gp. The normal  	 * bss follows. We keep it adjacent to simplify init code. | 
