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