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