1/*
2 *  linux/arch/m32r/boot/compressed/head.S
3 *
4 *  Copyright (c) 2001-2003	Hiroyuki Kondo, Hirokazu Takata,
5 *				Hitoshi Yamamoto, Takeo Takahashi
6 *  Copyright (c) 2004		Hirokazu Takata
7 */
8
9	.text
10#include <linux/linkage.h>
11#include <asm/addrspace.h>
12#include <asm/page.h>
13#include <asm/assembler.h>
14
15	/*
16	 * This code can be loaded anywhere, as long as output will not
17	 * overlap it.
18	 *
19	 * NOTE: This head.S should *NOT* be compiled with -fpic.
20	 *
21	 */
22
23	.global	startup
24	.global __bss_start, _ebss, end, zimage_data, zimage_len
25	__ALIGN
26startup:
27	ldi	r0, #0x0000			/* SPI, disable EI */
28	mvtc	r0, psw
29
30	ldi	r12, #-8
31	bl	1f
32	.fillinsn
331:
34	seth	r1, #high(CONFIG_MEMORY_START + 0x00400000) /* Start address */
35	add	r12, r14				/* Real address */
36	sub	r12, r1					/* difference */
37
38	.global got_len
39	seth	r3, #high(_GLOBAL_OFFSET_TABLE_+8)
40	or3	r3, r3, #low(_GLOBAL_OFFSET_TABLE_+12)
41	add	r3, r14
42
43	/* Update the contents of global offset table */
44	ldi	r1, #low(got_len)
45	srli	r1, #2
46	beqz	r1, 2f
47	.fillinsn
481:
49	ld	r2, @r3
50	add	r2, r12
51	st	r2, @r3
52	addi	r3, #4
53	addi	r1, #-1
54	bnez	r1, 1b
55	.fillinsn
562:
57	/* XXX: resolve plt */
58
59/*
60 * Clear BSS first so that there are no surprises...
61 */
62#ifdef CONFIG_ISA_DUAL_ISSUE
63	seth	r2, #high(__bss_start)
64	or3	r2, r2, #low(__bss_start)
65	add	r2, r12
66	seth	r3, #high(_ebss)
67	or3	r3, r3, #low(_ebss)
68	add	r3, r12
69	sub	r3, r2
70
71	; R4 = BSS size in longwords (rounded down)
72	mv	r4, r3		    ||	ldi	r1, #0
73	srli	r4, #4		    ||	addi	r2, #-4
74	beqz	r4, .Lendloop1
75.Lloop1:
76#ifndef CONFIG_CHIP_M32310
77	; Touch memory for the no-write-allocating cache.
78	ld	r0, @(4,r2)
79#endif
80	st	r1, @+r2	    ||	addi	r4, #-1
81	st	r1, @+r2
82	st	r1, @+r2
83	st	r1, @+r2	    ||	cmpeq	r1, r4	; R4 = 0?
84	bnc	.Lloop1
85.Lendloop1:
86	and3	r4, r3, #15
87	addi	r2, #4
88	beqz	r4, .Lendloop2
89.Lloop2:
90	stb	r1, @r2		    ||	addi	r4, #-1
91	addi	r2, #1
92	bnez	r4, .Lloop2
93.Lendloop2:
94
95#else /* not CONFIG_ISA_DUAL_ISSUE */
96	seth	r2, #high(__bss_start)
97	or3	r2, r2, #low(__bss_start)
98	add	r2, r12
99	seth	r3, #high(_ebss)
100	or3	r3, r3, #low(_ebss)
101	add	r3, r12
102	sub	r3, r2
103	mv	r4, r3
104	srli	r4, #2		; R4 = BSS size in longwords (rounded down)
105	ldi	r1, #0		; clear R1 for longwords store
106	addi	r2, #-4		; account for pre-inc store
107	beqz	r4, .Lendloop1	; any more to go?
108.Lloop1:
109	st	r1, @+r2	; yep, zero out another longword
110	addi	r4, #-1		; decrement count
111	bnez	r4, .Lloop1	; go do some more
112.Lendloop1:
113
114#endif /* not CONFIG_ISA_DUAL_ISSUE */
115
116	seth	r1, #high(end)
117	or3	r1, r1, #low(end)
118	add	r1, r12
119	mv	sp, r1
120
121/*
122 * decompress the kernel
123 */
124	mv	r0, sp
125	srli	r0, 31				/* MMU is ON or OFF */
126        seth	r1, #high(zimage_data)
127        or3	r1, r1, #low(zimage_data)
128	add	r1, r12
129        seth	r2, #high(zimage_len)
130        or3	r2, r2, #low(zimage_len)
131	mv	r3, sp
132
133	bl	decompress_kernel
134
135#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_VDEC2)
136	/* Cache flush */
137	ldi	r0, -1
138	ldi	r1, 0xd0	; invalidate i-cache, copy back d-cache
139	stb	r1, @r0
140#elif defined(CONFIG_CHIP_M32102)
141	/* Cache flush */
142	ldi	r0, -2
143	ldi	r1, 0x0100	; invalidate
144	stb	r1, @r0
145#elif defined(CONFIG_CHIP_M32104)
146	/* Cache flush */
147	ldi	r0, -2
148	ldi	r1, 0x0700	; invalidate i-cache, copy back d-cache
149	sth	r1, @r0
150#else
151#error "put your cache flush function, please"
152#endif
153
154	mv	r0, sp
155	srli	r0, 31				/* MMU is ON or OFF */
156	slli	r0, 31
157	or3	r0, r0, #0x2000
158	seth	r1, #high(CONFIG_MEMORY_START)
159	or	r0, r1
160	jmp	r0
161
162	.balign 512
163fake_headers_as_bzImage:
164	.short	0
165	.ascii	"HdrS"
166	.short	0x0202
167	.short	0
168	.short	0
169	.byte	0x00, 0x10
170	.short	0
171	.byte	0
172	.byte	1
173	.byte	0x00, 0x80
174	.long	0
175	.long	0
176
177