diff options
Diffstat (limited to 'arch/nios2/boot/compressed/head.S')
-rw-r--r-- | arch/nios2/boot/compressed/head.S | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/arch/nios2/boot/compressed/head.S b/arch/nios2/boot/compressed/head.S new file mode 100644 index 0000000000..15c6c48dd9 --- /dev/null +++ b/arch/nios2/boot/compressed/head.S @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw> + * + * Based on arch/nios2/kernel/head.S + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +/* + * This code can be loaded anywhere, eg FLASH ROM as reset vector, + * as long as output does not overlap it. + */ + +#include <linux/linkage.h> +#include <asm/cache.h> + + .text + .set noat +ENTRY(_start) + wrctl status, r0 /* disable interrupt */ + /* invalidate all instruction cache */ + movia r1, NIOS2_ICACHE_SIZE + movui r2, NIOS2_ICACHE_LINE_SIZE +1: initi r1 + sub r1, r1, r2 + bgt r1, r0, 1b + /* invalidate all data cache */ + movia r1, NIOS2_DCACHE_SIZE + movui r2, NIOS2_DCACHE_LINE_SIZE +1: initd 0(r1) + sub r1, r1, r2 + bgt r1, r0, 1b + + nextpc r1 /* Find out where we are */ +chkadr: + movia r2, chkadr + beq r1, r2, finish_move /* We are running in correct address, + done */ + /* move code, r1: src, r2: dest, r3: last dest */ + addi r1, r1, (_start - chkadr) /* Source */ + movia r2, _start /* Destination */ + movia r3, __bss_start /* End of copy */ +1: ldw r8, 0(r1) /* load a word from [r1] */ + stw r8, 0(r2) /* stort a word to dest [r2] */ + addi r1, r1, 4 /* inc the src addr */ + addi r2, r2, 4 /* inc the dest addr */ + blt r2, r3, 1b + /* flush the data cache after moving */ + movia r1, NIOS2_DCACHE_SIZE + movui r2, NIOS2_DCACHE_LINE_SIZE +1: flushd 0(r1) + sub r1, r1, r2 + bgt r1, r0, 1b + movia r1, finish_move + jmp r1 /* jmp to linked address */ + +finish_move: + /* zero out the .bss segment (uninitialized common data) */ + movia r2, __bss_start /* presume nothing is between */ + movia r1, _end /* the .bss and _end. */ +1: stb r0, 0(r2) + addi r2, r2, 1 + bne r1, r2, 1b + /* + * set up the stack pointer, some where higher than _end. + * The stack space must be greater than 32K for decompress. + */ + movia sp, 0x10000 + add sp, sp, r1 + /* save args passed from u-boot, maybe */ + addi sp, sp, -16 + stw r4, 0(sp) + stw r5, 4(sp) + stw r6, 8(sp) + stw r7, 12(sp) + /* decompress the kernel */ + call decompress_kernel + /* pass saved args to kernel */ + ldw r4, 0(sp) + ldw r5, 4(sp) + ldw r6, 8(sp) + ldw r7, 12(sp) + + /* flush all data cache after decompressing */ + movia r1, NIOS2_DCACHE_SIZE + movui r2, NIOS2_DCACHE_LINE_SIZE +1: flushd 0(r1) + sub r1, r1, r2 + bgt r1, r0, 1b + /* flush all instruction cache */ + movia r1, NIOS2_ICACHE_SIZE + movui r2, NIOS2_ICACHE_LINE_SIZE +1: flushi r1 + sub r1, r1, r2 + bgt r1, r0, 1b + flushp + /* jump to start real kernel */ + movia r1, (CONFIG_NIOS2_MEM_BASE | CONFIG_NIOS2_KERNEL_REGION_BASE) + jmp r1 + + .balign 512 +fake_headers_as_bzImage: + .short 0 + .ascii "HdrS" + .short 0x0202 + .short 0 + .short 0 + .byte 0x00, 0x10 + .short 0 + .byte 0 + .byte 1 + .byte 0x00, 0x80 + .long 0 + .long 0 |