[U-Boot] [RFC][PATCH 04/19] arm, arm1136, qong: add relocation support

Signed-off-by: Heiko Schocher hs@denx.de --- arch/arm/config.mk | 3 + arch/arm/cpu/arm1136/start.S | 176 ++++++++++++++------ arch/arm/cpu/arm1136/u-boot.lds | 14 ++- arch/arm/include/asm/config.h | 3 - arch/arm/include/asm/global_data.h | 6 + arch/arm/include/asm/u-boot-arm.h | 8 +- arch/arm/lib/board.c | 315 ++++++++++++++++++++++++++++++------ arch/arm/lib/interrupts.c | 15 ++- board/davedenx/qong/config.mk | 4 +- board/davedenx/qong/qong.c | 92 ++++++----- common/cmd_bdinfo.c | 1 + common/cmd_bmp.c | 6 + common/cmd_i2c.c | 6 + include/configs/qong.h | 9 + nand_spl/nand_boot.c | 5 + nand_spl/nand_boot_fsl_nfc.c | 5 + 16 files changed, 519 insertions(+), 149 deletions(-)
diff --git a/arch/arm/config.mk b/arch/arm/config.mk index e10dafc..be79f50 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -33,6 +33,9 @@ STANDALONE_LOAD_ADDR = 0xc100000 endif endif
+# needed for relocation +PLATFORM_RELFLAGS += -fPIC + PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S index 41eb82d..68ee309 100644 --- a/arch/arm/cpu/arm1136/start.S +++ b/arch/arm/cpu/arm1136/start.S @@ -85,13 +85,10 @@ _end_vect: ************************************************************************* */
+.globl _TEXT_BASE _TEXT_BASE: .word TEXT_BASE
-.globl _armboot_start -_armboot_start: - .word _start - /* * These are defined in the board-specific linker script. */ @@ -103,6 +100,30 @@ _bss_start: _bss_end: .word _end
+.globl _datarel_start +_datarel_start: + .word __datarel_start + +.globl _datarelrolocal_start +_datarelrolocal_start: + .word __datarelrolocal_start + +.globl _datarellocal_start +_datarellocal_start: + .word __datarellocal_start + +.globl _datarelro_start +_datarelro_start: + .word __datarelro_start + +.globl _got_start +_got_start: + .word __got_start + +.globl _got_end +_got_end: + .word __got_end + #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ .globl IRQ_STACK_START @@ -115,6 +136,11 @@ FIQ_STACK_START: .word 0x0badc0de #endif
+/* IRQ stack memory (calculated at run-time) + 8 bytes */ +.globl IRQ_STACK_START_IN +IRQ_STACK_START_IN: + .word 0x0badc0de + /* * the actual reset code */ @@ -151,65 +177,119 @@ next: bl cpu_init_crit #endif
-#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ -#ifndef CONFIG_PRELOADER - beq stack_setup -#endif /* CONFIG_PRELOADER */ +/* Set stackpointer in internal RAM to call board_init_f */ +call_board_init_f: + ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) + ldr r0,=0x00000000 + +#ifdef CONFIG_NAND_SPL + bl nand_boot +#else +#ifdef CONFIG_ONENAND_IPL + bl start_oneboot +#else + bl board_init_f +#endif /* CONFIG_ONENAND_IPL */ +#endif /* CONFIG_NAND_SPL */ + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + */ + .globl relocate_code +relocate_code: + mov r4, r0 /* save addr_sp */ + mov r5, r1 /* save addr of gd */ + mov r6, r2 /* save addr of destination */ + mov r7, r2 /* save addr of destination */
- ldr r2, _armboot_start + /* Set up the stack */ +stack_setup: + mov sp, r4 + + adr r0, _start + ldr r2, _TEXT_BASE ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */ + cmp r0, r6 + beq clear_bss
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ + ldmia r0!, {r9-r10} /* copy from source address [r0] */ + stmia r6!, {r9-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
- /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ -#ifdef CONFIG_PRELOADER - sub sp, r0, #128 /* leave 32 words for abort-stack */ -#else - sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#ifndef CONFIG_PRELOADER + /* fix got entries */ + ldr r1, _TEXT_BASE + mov r0, r7 /* reloc addr */ + ldr r2, _got_start /* addr in Flash */ + ldr r3, _got_end /* addr in Flash */ + sub r3, r3, r1 + add r3, r3, r0 + sub r2, r2, r1 + add r2, r2, r0 + +fixloop: + ldr r4, [r2] + sub r4, r4, r1 + add r4, r4, r0 + str r4, [r2] + add r2, r2, #4 + cmp r2, r3 + bne fixloop #endif - sub sp, r0, #12 /* leave 3 words for abort-stack */ -#endif /* CONFIG_PRELOADER */ - bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
clear_bss: - ldr r0, _bss_start /* find start of bss segment */ - ldr r1, _bss_end /* stop here */ +#ifndef CONFIG_PRELOADER + ldr r0, _bss_start + ldr r1, _bss_end + ldr r3, _TEXT_BASE /* Text base */ + mov r4, r7 /* reloc addr */ + sub r0, r0, r3 + add r0, r0, r4 + sub r1, r1, r3 + add r1, r1, r4 mov r2, #0x00000000 /* clear */
-#ifndef CONFIG_PRELOADER clbss_l:str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 bne clbss_l -#endif - - ldr pc, _start_armboot +#endif /* #ifndef CONFIG_PRELOADER */
+/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ #ifdef CONFIG_NAND_SPL -_start_armboot: .word nand_boot -#else -#ifdef CONFIG_ONENAND_IPL -_start_armboot: .word start_oneboot + ldr pc, _nand_boot + +_nand_boot: .word nand_boot #else -_start_armboot: .word start_armboot -#endif /* CONFIG_ONENAND_IPL */ -#endif /* CONFIG_NAND_SPL */ +jump_2_ram: + ldr r0, _TEXT_BASE + ldr r2, _board_init_r + sub r2, r2, r0 + add r2, r2, r7 /* position from board_init_r in RAM */ + /* setup parameters for board_init_r */ + mov r0, r5 /* gd_t */ + mov r1, r7 /* dest_addr */ + /* jump to it ... */ + mov lr, r2 + mov pc, lr + +_board_init_r: .word board_init_r +#endif
/* ************************************************************************* @@ -295,9 +375,7 @@ cpu_init_crit: sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
- ldr r2, _armboot_start - sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) - sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
@@ -328,9 +406,7 @@ cpu_init_crit: .endm
.macro get_bad_stack - ldr r13, _armboot_start @ setup our mode stack (enter in banked mode) - sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool - sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack + ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode)
str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr @@ -346,9 +422,7 @@ cpu_init_crit: .macro get_bad_stack_swi sub r13, r13, #4 @ space on current stack for scratch reg. str r0, [r13] @ save R0's value. - ldr r0, _armboot_start @ get data regions start - sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool - sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack + ldr r0, IRQ_STACK_START_IN @ get data regions start str lr, [r0] @ save caller lr in position 0 of saved stack mrs r0, spsr @ get the spsr str lr, [r0, #4] @ save spsr in position 1 of saved stack diff --git a/arch/arm/cpu/arm1136/u-boot.lds b/arch/arm/cpu/arm1136/u-boot.lds index e7eefc9..1db4b49 100644 --- a/arch/arm/cpu/arm1136/u-boot.lds +++ b/arch/arm/cpu/arm1136/u-boot.lds @@ -47,11 +47,23 @@ SECTIONS .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4); - .data : { *(.data) } + .data : { + *(.data) + __datarel_start = .; + *(.data.rel) + __datarelrolocal_start = .; + *(.data.rel.ro.local) + __datarellocal_start = .; + *(.data.rel.local) + __datarelro_start = .; + *(.data.rel.ro) + }
+ __got_start = .; . = ALIGN(4); .got : { *(.got) }
+ __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index b76fd8e..049c44e 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -21,7 +21,4 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_
-/* Relocation to SDRAM works on all ARM boards */ -#define CONFIG_RELOC_FIXUP_WORKS - #endif diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 02cfe45..192db7e 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -53,6 +53,12 @@ typedef struct global_data { phys_size_t ram_size; /* RAM size */ unsigned long reset_status; /* reset status register at boot */ #endif + unsigned long relocaddr; /* Start address of U-Boot in RAM */ + phys_size_t ram_size; /* RAM size */ + unsigned long mon_len; /* monitor len */ + unsigned long irq_sp; /* irq stack pointer */ + unsigned long start_addr_sp; /* start_addr_stackpointer */ + unsigned long reloc_off; void **jt; /* jump table */ } gd_t;
diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index 6d2f8bc..76f01a7 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -30,10 +30,15 @@ #define _U_BOOT_ARM_H_ 1
/* for the following variables, see start.S */ -extern ulong _armboot_start; /* code start */ +extern ulong _TEXT_BASE; /* code start */ extern ulong _bss_start; /* code + data end == BSS start */ extern ulong _bss_end; /* BSS end */ +extern ulong _datarel_start; +extern ulong _datarelrolocal_start; +extern ulong _datarellocal_start; +extern ulong _datarelro_start; extern ulong IRQ_STACK_START; /* top of IRQ stack */ +extern ulong IRQ_STACK_START_IN; /* 8 bytes in IRQ stack */ extern ulong FIQ_STACK_START; /* top of FIQ stack */
/* cpu/.../cpu.c */ @@ -47,6 +52,7 @@ int arch_misc_init(void); /* board/.../... */ int board_init(void); int dram_init (void); +void dram_init_banksize (void); void setup_serial_tag (struct tag **params); void setup_revision_tag (struct tag **params);
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index f5660a9..18ac183 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -126,7 +126,8 @@ static int init_baudrate (void) { char tmp[64]; /* long enough for environment variables */ int i = getenv_r ("baudrate", tmp, sizeof (tmp)); - gd->bd->bi_baudrate = gd->baudrate = (i > 0) + + gd->baudrate = (i > 0) ? (int) simple_strtoul (tmp, NULL, 10) : CONFIG_BAUDRATE;
@@ -137,7 +138,7 @@ 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); + _TEXT_BASE, _bss_start, _bss_end); #ifdef CONFIG_MODEM_SUPPORT debug ("Modem Support enabled\n"); #endif @@ -180,14 +181,6 @@ static int display_dram_config (void) return (0); }
-#ifndef CONFIG_SYS_NO_FLASH -static void display_flash_config (ulong size) -{ - puts ("Flash: "); - print_size (size, "\n"); -} -#endif /* CONFIG_SYS_NO_FLASH */ - #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) static int init_func_i2c (void) { @@ -238,9 +231,8 @@ init_fnc_t *init_sequence[] = { #if defined(CONFIG_ARCH_CPU_INIT) arch_cpu_init, /* basic arch cpu dependent setup */ #endif - board_init, /* basic board dependent setup */ -#if defined(CONFIG_USE_IRQ) - interrupt_init, /* set up exceptions */ +#if defined(CONFIG_BOARD_EARLY_INIT_F) + board_early_init_f, #endif timer_init, /* initialize timer */ #ifdef CONFIG_FSL_ESDHC @@ -264,30 +256,24 @@ init_fnc_t *init_sequence[] = { #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) arm_pci_init, #endif - display_dram_config, NULL, };
-void start_armboot (void) +void board_init_f (ulong bootflag) { + bd_t *bd; init_fnc_t **init_fnc_ptr; - char *s; -#if defined(CONFIG_VFD) || defined(CONFIG_LCD) - unsigned long addr; -#endif + gd_t *id; + ulong addr, addr_sp;
/* Pointer is writable since we allocated a register for it */ - gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)); + 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->bd = (bd_t*)((char*)gd - sizeof(bd_t)); - memset (gd->bd, 0, sizeof (bd_t)); - - gd->flags |= GD_FLG_RELOC;
- monitor_flash_len = _bss_start - _armboot_start; + gd->mon_len = _bss_end - _TEXT_BASE;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { @@ -295,14 +281,48 @@ void start_armboot (void) } }
- /* armboot_start is defined in the board-specific linker script */ - mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN, - CONFIG_SYS_MALLOC_LEN); + 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
-#ifndef CONFIG_SYS_NO_FLASH - /* configure available FLASH banks */ - display_flash_config (flash_init ()); -#endif /* CONFIG_SYS_NO_FLASH */ + 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 */ + + /* 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 @@ -311,27 +331,189 @@ void start_armboot (void) /* * reserve memory for VFD display (always full pages) */ - /* bss_end is defined in the board-specific linker script */ - addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); - vfd_setmem (addr); + addr -= vfd_setmem (addr); gd->fb_base = addr; #endif /* CONFIG_VFD */
#ifdef CONFIG_LCD - /* board init may have inited fb_base */ - if (!gd->fb_base) { -# ifndef PAGE_SIZE -# define PAGE_SIZE 4096 -# endif + /* 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, ""); /* - * reserve memory for LCD display (always full pages) + * Compute and print flash CRC if flashchecksum is set to 'y' + * + * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX */ - /* bss_end is defined in the board-specific linker script */ - addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); - lcd_setmem (addr); - gd->fb_base = addr; + 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 /* CONFIG_LCD */ +#endif
#if defined(CONFIG_CMD_NAND) puts ("NAND: "); @@ -355,10 +537,6 @@ void start_armboot (void) drv_vfd_init(); #endif /* CONFIG_VFD */
-#ifdef CONFIG_SERIAL_MULTI - serial_initialize(); -#endif - /* IP Address */ gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
@@ -382,6 +560,8 @@ void start_armboot (void) misc_init_r (); #endif
+ /* set up exceptions */ + interrupt_init (); /* enable exceptions */ enable_interrupts ();
@@ -437,6 +617,41 @@ extern void davinci_eth_set_mac_addr (const u_int8_t *addr); 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 (); diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c index 1f2b815..74ff5ce 100644 --- a/arch/arm/lib/interrupts.c +++ b/arch/arm/lib/interrupts.c @@ -38,15 +38,16 @@ #include <common.h> #include <asm/proc-armv/ptrace.h>
-#ifdef CONFIG_USE_IRQ DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_USE_IRQ int interrupt_init (void) { /* * setup up stacks if necessary */ - IRQ_STACK_START = _armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4; + IRQ_STACK_START = gd->irq_sp - 4; + IRQ_STACK_START_IN = gd->irq_sp + 8; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
return arch_interrupt_init(); @@ -81,6 +82,16 @@ int disable_interrupts (void) return (old & 0x80) == 0; } #else +int interrupt_init (void) +{ + /* + * setup up stacks if necessary + */ + IRQ_STACK_START_IN = gd->irq_sp + 8; + + return 0; +} + void enable_interrupts (void) { return; diff --git a/board/davedenx/qong/config.mk b/board/davedenx/qong/config.mk index d8d0a57..39c1203 100644 --- a/board/davedenx/qong/config.mk +++ b/board/davedenx/qong/config.mk @@ -1 +1,3 @@ -TEXT_BASE = 0x8ff00000 +TEXT_BASE = 0xa0000000 + +# PLATFORM_CPPFLAGS += -DDEBUG diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c index 781333b..88d1231 100644 --- a/board/davedenx/qong/qong.c +++ b/board/davedenx/qong/qong.c @@ -33,11 +33,17 @@ DECLARE_GLOBAL_DATA_PTR;
int dram_init (void) { + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size((volatile void *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + return 0; +} + +void dram_init_banksize (void) +{ gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = get_ram_size((volatile void *)PHYS_SDRAM_1, - PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[0].size = gd->ram_size;
- return 0; }
static void qong_fpga_reset(void) @@ -49,6 +55,49 @@ static void qong_fpga_reset(void) udelay(300); }
+int board_early_init_f (void) +{ +#ifdef CONFIG_QONG_FPGA + /* CS1: FPGA/Network Controller/GPIO */ + /* 16-bit, no DTACK */ + __REG(CSCR_U(1)) = 0x00000A01; + __REG(CSCR_L(1)) = 0x20040501; + __REG(CSCR_A(1)) = 0x04020C00; + + /* setup pins for FPGA */ + mx31_gpio_mux(IOMUX_MODE(0x76, MUX_CTL_GPIO)); + mx31_gpio_mux(IOMUX_MODE(0x7e, MUX_CTL_GPIO)); + mx31_gpio_mux(IOMUX_MODE(0x91, MUX_CTL_OUT_FUNC | MUX_CTL_IN_GPIO)); + mx31_gpio_mux(IOMUX_MODE(0x92, MUX_CTL_GPIO)); + mx31_gpio_mux(IOMUX_MODE(0x93, MUX_CTL_GPIO)); + + /* FPGA reset Pin */ + /* rstn = 0 */ + mx31_gpio_set(QONG_FPGA_RST_PIN, 0); + mx31_gpio_direction(QONG_FPGA_RST_PIN, MX31_GPIO_DIRECTION_OUT); + + /* set interrupt pin as input */ + mx31_gpio_direction(QONG_FPGA_IRQ_PIN, MX31_GPIO_DIRECTION_IN); + +#endif + + /* setup pins for UART1 */ + mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX); + mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX); + mx31_gpio_mux(MUX_RTS1__UART1_RTS_B); + mx31_gpio_mux(MUX_CTS1__UART1_CTS_B); + + /* setup pins for SPI (pmic) */ + mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B); + mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI); + mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO); + mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK); + mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B); + + return 0; + +} + int board_init (void) { /* Chip selects */ @@ -99,43 +148,6 @@ int board_init (void) (0 << 0) /* FCE */ );
-#ifdef CONFIG_QONG_FPGA - /* CS1: FPGA/Network Controller/GPIO */ - /* 16-bit, no DTACK */ - __REG(CSCR_U(1)) = 0x00000A01; - __REG(CSCR_L(1)) = 0x20040501; - __REG(CSCR_A(1)) = 0x04020C00; - - /* setup pins for FPGA */ - mx31_gpio_mux(IOMUX_MODE(0x76, MUX_CTL_GPIO)); - mx31_gpio_mux(IOMUX_MODE(0x7e, MUX_CTL_GPIO)); - mx31_gpio_mux(IOMUX_MODE(0x91, MUX_CTL_OUT_FUNC | MUX_CTL_IN_GPIO)); - mx31_gpio_mux(IOMUX_MODE(0x92, MUX_CTL_GPIO)); - mx31_gpio_mux(IOMUX_MODE(0x93, MUX_CTL_GPIO)); - - /* FPGA reset Pin */ - /* rstn = 0 */ - mx31_gpio_set(QONG_FPGA_RST_PIN, 0); - mx31_gpio_direction(QONG_FPGA_RST_PIN, MX31_GPIO_DIRECTION_OUT); - - /* set interrupt pin as input */ - mx31_gpio_direction(QONG_FPGA_IRQ_PIN, MX31_GPIO_DIRECTION_IN); - -#endif - - /* setup pins for UART1 */ - mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX); - mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX); - mx31_gpio_mux(MUX_RTS1__UART1_RTS_B); - mx31_gpio_mux(MUX_CTS1__UART1_CTS_B); - - /* setup pins for SPI (pmic) */ - mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B); - mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI); - mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO); - mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK); - mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B); - /* board id for linux */ gd->bd->bi_arch_number = MACH_TYPE_QONG; gd->bd->bi_boot_params = (0x80000100); /* adress of boot parameters */ diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index cc81543..57a2243 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -343,6 +343,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf ("ip_addr = %pI4\n", &bd->bi_ip_addr); #endif printf ("baudrate = %d bps\n", bd->bi_baudrate); + print_num ("irq_sp", gd->irq_sp); /* irq stack pointer */
return 0; } diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index d51cc55..6fa8a15 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -137,6 +137,12 @@ static cmd_tbl_t cmd_bmp_sub[] = { U_BOOT_CMD_MKENT(display, 5, 0, do_bmp_display, "", ""), };
+#ifndef CONFIG_RELOC_FIXUP_WORKS +void bmp_reloc(void) { + fixup_cmdtable(cmd_bmp_sub, ARRAY_SIZE(cmd_bmp_sub)); +} +#endif + /* * Subroutine: do_bmp * diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 371e022..a1a84a1 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -1287,6 +1287,12 @@ static cmd_tbl_t cmd_i2c_sub[] = { U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""), };
+#ifndef CONFIG_RELOC_FIXUP_WORKS +void i2c_reloc(void) { + fixup_cmdtable(cmd_i2c_sub, ARRAY_SIZE(cmd_i2c_sub)); +} +#endif + static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { cmd_tbl_t *c; diff --git a/include/configs/qong.h b/include/configs/qong.h index 100fa3f..0d6718c 100644 --- a/include/configs/qong.h +++ b/include/configs/qong.h @@ -281,4 +281,13 @@ extern int qong_nand_rdy(void *chip); "mtdparts=physmap-flash.0:384k(U-Boot),128k(env1)," \ "128k(env2),2432k(kernel),13m(ramdisk),-(user)"
+/* additions for new relocation code, must added to all boards */ +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_END IRAM_SIZE +#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET) + +#define CONFIG_BOARD_EARLY_INIT_F 1 + #endif /* __CONFIG_H */ diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c index b9fd6f5..ded0c0e 100644 --- a/nand_spl/nand_boot.c +++ b/nand_spl/nand_boot.c @@ -221,6 +221,11 @@ static int nand_load(struct mtd_info *mtd, unsigned int offs, return 0; }
+void board_init_f (ulong bootflag) +{ + relocate_code (TEXT_BASE - TOTAL_MALLOC_LEN, NULL, TEXT_BASE); +} + /* * The main entry for NAND booting. It's necessary that SDRAM is already * configured and available since this code loads the main U-Boot image diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index bfae30e..9720f6a 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -265,6 +265,11 @@ static int nand_load(unsigned int from, unsigned int size, unsigned char *buf) return 0; }
+void board_init_f (ulong bootflag) +{ + relocate_code (TEXT_BASE - TOTAL_MALLOC_LEN, NULL, TEXT_BASE); +} + /* * The main entry for NAND booting. It's necessary that SDRAM is already * configured and available since this code loads the main U-Boot image
participants (1)
-
Heiko Schocher