1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#define KERNEL_LOAD_ADR 0x40004000
21
22#include <linux/types.h>
23
24#ifdef CONFIG_ETRAX_ARCH_V32
25#include <hwregs/reg_rdwr.h>
26#include <hwregs/reg_map.h>
27#include <hwregs/ser_defs.h>
28#include <hwregs/pinmux_defs.h>
29#ifdef CONFIG_CRIS_MACH_ARTPEC3
30#include <hwregs/clkgen_defs.h>
31#endif
32#else
33#include <arch/svinto.h>
34#endif
35
36
37
38
39
40#define OF(args) args
41#define STATIC static
42
43void *memset(void *s, int c, size_t n);
44void *memcpy(void *__dest, __const void *__src, size_t __n);
45
46#define memzero(s, n) memset((s), 0, (n))
47
48typedef unsigned char uch;
49typedef unsigned short ush;
50typedef unsigned long ulg;
51
52#define WSIZE 0x8000
53
54
55static uch *inbuf;
56static uch window[WSIZE];
57
58unsigned inptr = 0;
59
60
61
62
63static unsigned outcnt = 0;
64
65
66#define ASCII_FLAG 0x01
67#define CONTINUATION 0x02
68#define EXTRA_FIELD 0x04
69#define ORIG_NAME 0x08
70#define COMMENT 0x10
71#define ENCRYPTED 0x20
72#define RESERVED 0xC0
73
74#define get_byte() (inbuf[inptr++])
75
76
77#ifdef DEBUG
78# define Assert(cond, msg) do { \
79 if (!(cond)) \
80 error(msg); \
81 } while (0)
82# define Trace(x) fprintf x
83# define Tracev(x) do { \
84 if (verbose) \
85 fprintf x; \
86 } while (0)
87# define Tracevv(x) do { \
88 if (verbose > 1) \
89 fprintf x; \
90 } while (0)
91# define Tracec(c, x) do { \
92 if (verbose && (c)) \
93 fprintf x; \
94 } while (0)
95# define Tracecv(c, x) do { \
96 if (verbose > 1 && (c)) \
97 fprintf x; \
98 } while (0)
99#else
100# define Assert(cond, msg)
101# define Trace(x)
102# define Tracev(x)
103# define Tracevv(x)
104# define Tracec(c, x)
105# define Tracecv(c, x)
106#endif
107
108static void flush_window(void);
109static void error(char *m);
110static void aputs(const char *s);
111
112extern char *input_data;
113
114static long bytes_out;
115static uch *output_data;
116static unsigned long output_ptr;
117
118
119
120extern int _end;
121static long free_mem_ptr = (long)&_end;
122static long free_mem_end_ptr;
123
124#include "../../../../../lib/inflate.c"
125
126
127
128#ifdef CONFIG_ETRAX_ARCH_V32
129static inline void serout(const char *s, reg_scope_instances regi_ser)
130{
131 reg_ser_rs_stat_din rs;
132 reg_ser_rw_dout dout = {.data = *s};
133
134 do {
135 rs = REG_RD(ser, regi_ser, rs_stat_din);
136 }
137 while (!rs.tr_rdy);
138
139 REG_WR(ser, regi_ser, rw_dout, dout);
140}
141#define SEROUT(S, N) \
142 do { \
143 serout(S, regi_ser ## N); \
144 s++; \
145 } while (0)
146#else
147#define SEROUT(S, N) do { \
148 while (!(*R_SERIAL ## N ## _STATUS & (1 << 5))) \
149 ; \
150 *R_SERIAL ## N ## _TR_DATA = *s++; \
151 } while (0)
152#endif
153
154static void aputs(const char *s)
155{
156#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
157 while (*s) {
158#ifdef CONFIG_ETRAX_DEBUG_PORT0
159 SEROUT(s, 0);
160#endif
161#ifdef CONFIG_ETRAX_DEBUG_PORT1
162 SEROUT(s, 1);
163#endif
164#ifdef CONFIG_ETRAX_DEBUG_PORT2
165 SEROUT(s, 2);
166#endif
167#ifdef CONFIG_ETRAX_DEBUG_PORT3
168 SEROUT(s, 3);
169#endif
170 }
171#endif
172}
173
174void *memset(void *s, int c, size_t n)
175{
176 int i;
177 char *ss = (char*)s;
178
179 for (i=0;i<n;i++) ss[i] = c;
180
181 return s;
182}
183
184void *memcpy(void *__dest, __const void *__src, size_t __n)
185{
186 int i;
187 char *d = (char *)__dest, *s = (char *)__src;
188
189 for (i = 0; i < __n; i++)
190 d[i] = s[i];
191
192 return __dest;
193}
194
195
196
197
198
199
200static void flush_window(void)
201{
202 ulg c = crc;
203 unsigned n;
204 uch *in, *out, ch;
205
206 in = window;
207 out = &output_data[output_ptr];
208 for (n = 0; n < outcnt; n++) {
209 ch = *out = *in;
210 out++;
211 in++;
212 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
213 }
214 crc = c;
215 bytes_out += (ulg)outcnt;
216 output_ptr += (ulg)outcnt;
217 outcnt = 0;
218}
219
220static void error(char *x)
221{
222 aputs("\n\n");
223 aputs(x);
224 aputs("\n\n -- System halted\n");
225
226 while(1);
227}
228
229void setup_normal_output_buffer(void)
230{
231 output_data = (char *)KERNEL_LOAD_ADR;
232}
233
234#ifdef CONFIG_ETRAX_ARCH_V32
235static inline void serial_setup(reg_scope_instances regi_ser)
236{
237 reg_ser_rw_xoff xoff;
238 reg_ser_rw_tr_ctrl tr_ctrl;
239 reg_ser_rw_rec_ctrl rec_ctrl;
240 reg_ser_rw_tr_baud_div tr_baud;
241 reg_ser_rw_rec_baud_div rec_baud;
242
243
244 xoff = REG_RD(ser, regi_ser, rw_xoff);
245
246 xoff.chr = 0;
247 xoff.automatic = regk_ser_no;
248
249 REG_WR(ser, regi_ser, rw_xoff, xoff);
250
251
252 tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
253 rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
254 tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
255 rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
256
257 tr_ctrl.stop_bits = 1;
258 tr_ctrl.en = 1;
259 rec_ctrl.en = 1;
260
261
262
263
264
265
266 tr_ctrl.base_freq = regk_ser_f29_493;
267 rec_ctrl.base_freq = regk_ser_f29_493;
268 tr_baud.div = (29493000 / 8) / 115200;
269 rec_baud.div = (29493000 / 8) / 115200;
270
271 REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
272 REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
273 REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
274 REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
275}
276#endif
277
278void decompress_kernel(void)
279{
280 char revision;
281 char compile_rev;
282
283#ifdef CONFIG_ETRAX_ARCH_V32
284
285 compile_rev = 32;
286#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
287 defined(CONFIG_ETRAX_DEBUG_PORT2) || \
288 defined(CONFIG_ETRAX_DEBUG_PORT3)
289 reg_pinmux_rw_hwprot hwprot;
290
291#ifdef CONFIG_CRIS_MACH_ARTPEC3
292 reg_clkgen_rw_clk_ctrl clk_ctrl;
293
294
295
296 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
297 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
298 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
299#endif
300
301
302 hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
303#endif
304
305
306#ifdef CONFIG_ETRAX_DEBUG_PORT0
307 serial_setup(regi_ser0);
308#endif
309#ifdef CONFIG_ETRAX_DEBUG_PORT1
310 hwprot.ser1 = regk_pinmux_yes;
311 serial_setup(regi_ser1);
312#endif
313#ifdef CONFIG_ETRAX_DEBUG_PORT2
314 hwprot.ser2 = regk_pinmux_yes;
315 serial_setup(regi_ser2);
316#endif
317#ifdef CONFIG_ETRAX_DEBUG_PORT3
318 hwprot.ser3 = regk_pinmux_yes;
319 serial_setup(regi_ser3);
320#endif
321#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
322 defined(CONFIG_ETRAX_DEBUG_PORT2) || \
323 defined(CONFIG_ETRAX_DEBUG_PORT3)
324 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
325#endif
326
327
328 inbuf = input_data;
329#else
330
331 compile_rev = 10;
332
333
334 inbuf = input_data;
335
336#ifdef CONFIG_ETRAX_DEBUG_PORT0
337 *R_SERIAL0_XOFF = 0;
338 *R_SERIAL0_BAUD = 0x99;
339 *R_SERIAL0_TR_CTRL = 0x40;
340#endif
341#ifdef CONFIG_ETRAX_DEBUG_PORT1
342 *R_SERIAL1_XOFF = 0;
343 *R_SERIAL1_BAUD = 0x99;
344 *R_SERIAL1_TR_CTRL = 0x40;
345#endif
346#ifdef CONFIG_ETRAX_DEBUG_PORT2
347 *R_GEN_CONFIG = 0x08;
348 *R_SERIAL2_XOFF = 0;
349 *R_SERIAL2_BAUD = 0x99;
350 *R_SERIAL2_TR_CTRL = 0x40;
351#endif
352#ifdef CONFIG_ETRAX_DEBUG_PORT3
353 *R_GEN_CONFIG = 0x100;
354 *R_SERIAL3_XOFF = 0;
355 *R_SERIAL3_BAUD = 0x99;
356 *R_SERIAL3_TR_CTRL = 0x40;
357#endif
358#endif
359
360 setup_normal_output_buffer();
361
362 makecrc();
363
364 __asm__ volatile ("move $vr,%0" : "=rm" (revision));
365 if (revision < compile_rev) {
366#ifdef CONFIG_ETRAX_ARCH_V32
367 aputs("You need at least ETRAX FS to run Linux 2.6/crisv32\n");
368#else
369 aputs("You need an ETRAX 100LX to run linux 2.6/crisv10\n");
370#endif
371 while(1);
372 }
373
374 aputs("Uncompressing Linux...\n");
375 gunzip();
376 aputs("Done. Now booting the kernel\n");
377}
378