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
58/*
59 * Clear BSS first so that there are no surprises...
60 */
61#ifdef CONFIG_ISA_DUAL_ISSUE
62	seth	r2, #high(__bss_start)
63	or3	r2, r2, #low(__bss_start)
64	add	r2, r12
65	seth	r3, #high(_ebss)
66	or3	r3, r3, #low(_ebss)
67	add	r3, r12
68	sub	r3, r2
69
70	; R4 = BSS size in longwords (rounded down)
71	mv	r4, r3		    ||	ldi	r1, #0
72	srli	r4, #4		    ||	addi	r2, #-4
73	beqz	r4, .Lendloop1
74.Lloop1:
75#ifndef CONFIG_CHIP_M32310
76	; Touch memory for the no-write-allocating cache.
77	ld	r0, @(4,r2)
78#endif
79	st	r1, @+r2	    ||	addi	r4, #-1
80	st	r1, @+r2
81	st	r1, @+r2
82	st	r1, @+r2	    ||	cmpeq	r1, r4	; R4 = 0?
83	bnc	.Lloop1
84.Lendloop1:
85	and3	r4, r3, #15
86	addi	r2, #4
87	beqz	r4, .Lendloop2
88.Lloop2:
89	stb	r1, @r2		    ||	addi	r4, #-1
90	addi	r2, #1
91	bnez	r4, .Lloop2
92.Lendloop2:
93
94#else /* not CONFIG_ISA_DUAL_ISSUE */
95	seth	r2, #high(__bss_start)
96	or3	r2, r2, #low(__bss_start)
97	add	r2, r12
98	seth	r3, #high(_ebss)
99	or3	r3, r3, #low(_ebss)
100	add	r3, r12
101	sub	r3, r2
102	mv	r4, r3
103	srli	r4, #2		; R4 = BSS size in longwords (rounded down)
104	ldi	r1, #0		; clear R1 for longwords store
105	addi	r2, #-4		; account for pre-inc store
106	beqz	r4, .Lendloop1	; any more to go?
107.Lloop1:
108	st	r1, @+r2	; yep, zero out another longword
109	addi	r4, #-1		; decrement count
110	bnez	r4, .Lloop1	; go do some more
111.Lendloop1:
112
113#endif /* not CONFIG_ISA_DUAL_ISSUE */
114
115	seth	r1, #high(end)
116	or3	r1, r1, #low(end)
117	add	r1, r12
118	mv	sp, r1
119
120/*
121 * decompress the kernel
122 */
123	mv	r0, sp
124	srli	r0, 31				/* MMU is ON or OFF */
125        seth	r1, #high(zimage_data)
126        or3	r1, r1, #low(zimage_data)
127	add	r1, r12
128        seth	r2, #high(zimage_len)
129        or3	r2, r2, #low(zimage_len)
130	mv	r3, sp
131
132	bl	decompress_kernel
133
134#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || \
135	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