|  | /* | 
|  | * 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 |