1 /*
2  * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
3  *
4  * Based on arch/nios2/kernel/head.S
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License. See the file "COPYING" in the main directory of this archive
8  * for more details.
9  *
10  */
11 
12 /*
13  *  This code can be loaded anywhere, eg FLASH ROM as reset vector,
14  *  as long as output does not overlap it.
15  */
16 
17 #include <linux/linkage.h>
18 #include <asm/cache.h>
19 
20 	.text
21 	.set noat
22 ENTRY(_start)
23 	wrctl	status, r0		/* disable interrupt */
24 	/* invalidate all instruction cache */
25 	movia	r1, NIOS2_ICACHE_SIZE
26 	movui	r2, NIOS2_ICACHE_LINE_SIZE
27 1:	initi	r1
28 	sub	r1, r1, r2
29 	bgt	r1, r0, 1b
30 	/* invalidate all data cache */
31 	movia	r1, NIOS2_DCACHE_SIZE
32 	movui	r2, NIOS2_DCACHE_LINE_SIZE
33 1:	initd	0(r1)
34 	sub	r1, r1, r2
35 	bgt	r1, r0, 1b
36 
37 	nextpc	r1			/* Find out where we are */
38 chkadr:
39 	movia	r2, chkadr
40 	beq	r1, r2, finish_move	/* We are running in correct address,
41 					   done */
42 	/* move code, r1: src, r2: dest, r3: last dest */
43 	addi	r1, r1, (_start - chkadr)	/* Source */
44 	movia	r2, _start		/* Destination */
45 	movia	r3, __bss_start		/* End of copy */
46 1:	ldw	r8, 0(r1)		/* load a word from [r1] */
47 	stw	r8, 0(r2)		/* stort a word to dest [r2] */
48 	addi	r1, r1, 4		/* inc the src addr */
49 	addi	r2, r2, 4		/* inc the dest addr */
50 	blt	r2, r3, 1b
51 	/* flush the data cache after moving */
52 	movia	r1, NIOS2_DCACHE_SIZE
53 	movui	r2, NIOS2_DCACHE_LINE_SIZE
54 1:	flushd	0(r1)
55 	sub	r1, r1, r2
56 	bgt	r1, r0, 1b
57 	movia	r1, finish_move
58 	jmp	r1			/* jmp to linked address */
59 
60 finish_move:
61 	/* zero out the .bss segment (uninitialized common data) */
62 	movia	r2, __bss_start		/* presume nothing is between */
63 	movia	r1, _end		/* the .bss and _end. */
64 1: 	stb	r0, 0(r2)
65 	addi	r2, r2, 1
66 	bne	r1, r2, 1b
67 	/*
68 	 * set up the stack pointer, some where higher than _end.
69 	 * The stack space must be greater than 32K for decompress.
70 	 */
71 	movia	sp, 0x10000
72 	add	sp, sp, r1
73 	/* save args passed from u-boot, maybe */
74 	addi	sp, sp, -16
75 	stw	r4, 0(sp)
76 	stw	r5, 4(sp)
77 	stw	r6, 8(sp)
78 	stw	r7, 12(sp)
79 	/* decompress the kernel */
80 	call	decompress_kernel
81 	/* pass saved args to kernel */
82 	ldw	r4, 0(sp)
83 	ldw	r5, 4(sp)
84 	ldw	r6, 8(sp)
85 	ldw	r7, 12(sp)
86 
87 	/* flush all data cache after decompressing */
88 	movia	r1, NIOS2_DCACHE_SIZE
89 	movui	r2, NIOS2_DCACHE_LINE_SIZE
90 1:	flushd	0(r1)
91 	sub	r1, r1, r2
92 	bgt	r1, r0, 1b
93 	/* flush all instruction cache */
94 	movia	r1, NIOS2_ICACHE_SIZE
95 	movui	r2, NIOS2_ICACHE_LINE_SIZE
96 1:	flushi	r1
97 	sub	r1, r1, r2
98 	bgt	r1, r0, 1b
99 	flushp
100 	/* jump to start real kernel */
101 	movia	r1, (CONFIG_NIOS2_MEM_BASE | CONFIG_NIOS2_KERNEL_REGION_BASE)
102 	jmp	r1
103 
104 	.balign 512
105 fake_headers_as_bzImage:
106 	.short	0
107 	.ascii	"HdrS"
108 	.short	0x0202
109 	.short	0
110 	.short	0
111 	.byte	0x00, 0x10
112 	.short	0
113 	.byte	0
114 	.byte	1
115 	.byte	0x00, 0x80
116 	.long	0
117 	.long	0
118