]> bbs.cooldavid.org Git - net-next-2.6.git/blob - arch/cris/arch-v10/boot/compressed/misc.c
59961f20fabb2bddf4c390dd44f9fccaa492f58e
[net-next-2.6.git] / arch / cris / arch-v10 / boot / compressed / misc.c
1 /*
2  * misc.c
3  *
4  * This is a collection of several routines from gzip-1.0.3
5  * adapted for Linux.
6  *
7  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8  * puts by Nick Holloway 1993, better puts by Martin Mares 1995
9  * adaptation for Linux/CRIS Axis Communications AB, 1999
10  *
11  */
12
13 /* where the piggybacked kernel image expects itself to live.
14  * it is the same address we use when we network load an uncompressed
15  * image into DRAM, and it is the address the kernel is linked to live
16  * at by vmlinux.lds.S
17  */
18
19 #define KERNEL_LOAD_ADR 0x40004000
20
21
22 #include <linux/types.h>
23 #include <asm/arch/svinto.h>
24
25 /*
26  * gzip declarations
27  */
28
29 #define OF(args)  args
30 #define STATIC static
31
32 void* memset(void* s, int c, size_t n);
33 void* memcpy(void* __dest, __const void* __src, size_t __n);
34
35 #define memzero(s, n)     memset ((s), 0, (n))
36
37
38 typedef unsigned char  uch;
39 typedef unsigned short ush;
40 typedef unsigned long  ulg;
41
42 #define WSIZE 0x8000            /* Window size must be at least 32k, */
43                                 /* and a power of two */
44
45 static uch *inbuf;           /* input buffer */
46 static uch window[WSIZE];    /* Sliding window buffer */
47
48 unsigned inptr = 0;     /* index of next byte to be processed in inbuf
49                          * After decompression it will contain the
50                          * compressed size, and head.S will read it.
51                          */
52
53 static unsigned outcnt = 0;  /* bytes in output buffer */
54
55 /* gzip flag byte */
56 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
57 #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
58 #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
59 #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
60 #define COMMENT      0x10 /* bit 4 set: file comment present */
61 #define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
62 #define RESERVED     0xC0 /* bit 6,7:   reserved */
63
64 #define get_byte() inbuf[inptr++]       
65         
66 /* Diagnostic functions */
67 #ifdef DEBUG
68 #  define Assert(cond,msg) {if(!(cond)) error(msg);}
69 #  define Trace(x) fprintf x
70 #  define Tracev(x) {if (verbose) fprintf x ;}
71 #  define Tracevv(x) {if (verbose>1) fprintf x ;}
72 #  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
73 #  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
74 #else
75 #  define Assert(cond,msg)
76 #  define Trace(x)
77 #  define Tracev(x)
78 #  define Tracevv(x)
79 #  define Tracec(c,x)
80 #  define Tracecv(c,x)
81 #endif
82
83 static void flush_window(void);
84 static void error(char *m);
85
86 extern char *input_data;  /* lives in head.S */
87
88 static long bytes_out = 0;
89 static uch *output_data;
90 static unsigned long output_ptr = 0;
91  
92 static void *malloc(int size);
93 static void free(void *where);
94 static void gzip_mark(void **);
95 static void gzip_release(void **);
96  
97 static void puts(const char *);
98
99 /* the "heap" is put directly after the BSS ends, at end */
100   
101 extern int _end;
102 static long free_mem_ptr = (long)&_end;
103  
104 #include "../../../../../lib/inflate.c"
105
106 static void *malloc(int size)
107 {
108         void *p;
109
110         if (size <0) error("Malloc error");
111
112         free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
113
114         p = (void *)free_mem_ptr;
115         free_mem_ptr += size;
116
117         return p;
118 }
119
120 static void free(void *where)
121 {       /* Don't care */
122 }
123
124 static void gzip_mark(void **ptr)
125 {
126         *ptr = (void *) free_mem_ptr;
127 }
128
129 static void gzip_release(void **ptr)
130 {
131         free_mem_ptr = (long) *ptr;
132 }
133
134 /* decompressor info and error messages to serial console */
135
136 static void
137 puts(const char *s)
138 {
139 #ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
140         while(*s) {
141 #ifdef CONFIG_ETRAX_DEBUG_PORT0
142                 while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
143                 *R_SERIAL0_TR_DATA = *s++;
144 #endif
145 #ifdef CONFIG_ETRAX_DEBUG_PORT1
146                 while(!(*R_SERIAL1_STATUS & (1 << 5))) ;
147                 *R_SERIAL1_TR_DATA = *s++;
148 #endif
149 #ifdef CONFIG_ETRAX_DEBUG_PORT2
150                 while(!(*R_SERIAL2_STATUS & (1 << 5))) ;
151                 *R_SERIAL2_TR_DATA = *s++;
152 #endif
153 #ifdef CONFIG_ETRAX_DEBUG_PORT3
154                 while(!(*R_SERIAL3_STATUS & (1 << 5))) ;
155                 *R_SERIAL3_TR_DATA = *s++;
156 #endif
157         }
158 #endif
159 }
160
161 void*
162 memset(void* s, int c, size_t n)
163 {
164         int i;
165         char *ss = (char*)s;
166
167         for (i=0;i<n;i++) ss[i] = c;
168
169    return s;
170 }
171
172 void*
173 memcpy(void* __dest, __const void* __src,
174                             size_t __n)
175 {
176         int i;
177         char *d = (char *)__dest, *s = (char *)__src;
178
179         for (i=0;i<__n;i++) d[i] = s[i];
180
181    return __dest;
182 }
183
184 /* ===========================================================================
185  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
186  * (Used for the decompressed data only.)
187  */
188
189 static void
190 flush_window()
191 {
192     ulg c = crc;         /* temporary variable */
193     unsigned n;
194     uch *in, *out, ch;
195     
196     in = window;
197     out = &output_data[output_ptr]; 
198     for (n = 0; n < outcnt; n++) {
199             ch = *out++ = *in++;
200             c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
201     }
202     crc = c;
203     bytes_out += (ulg)outcnt;
204     output_ptr += (ulg)outcnt;
205     outcnt = 0;
206 }
207
208 static void
209 error(char *x)
210 {
211         puts("\n\n");
212         puts(x);
213         puts("\n\n -- System halted\n");
214
215         while(1);       /* Halt */
216 }
217
218 void setup_normal_output_buffer(void)
219 {
220         output_data = (char *)KERNEL_LOAD_ADR;
221 }
222
223 void decompress_kernel(void)
224 {
225         char revision;
226         
227         /* input_data is set in head.S */
228         inbuf = input_data;
229
230 #ifdef CONFIG_ETRAX_DEBUG_PORT0
231         *R_SERIAL0_XOFF = 0;
232         *R_SERIAL0_BAUD = 0x99;
233         *R_SERIAL0_TR_CTRL = 0x40;
234 #endif
235 #ifdef CONFIG_ETRAX_DEBUG_PORT1
236         *R_SERIAL1_XOFF = 0;
237         *R_SERIAL1_BAUD = 0x99;
238         *R_SERIAL1_TR_CTRL = 0x40;
239 #endif
240 #ifdef CONFIG_ETRAX_DEBUG_PORT2
241         *R_GEN_CONFIG = 0x08;
242         *R_SERIAL2_XOFF = 0;
243         *R_SERIAL2_BAUD = 0x99;
244         *R_SERIAL2_TR_CTRL = 0x40;
245 #endif
246 #ifdef CONFIG_ETRAX_DEBUG_PORT3
247         *R_GEN_CONFIG = 0x100;
248         *R_SERIAL3_XOFF = 0;
249         *R_SERIAL3_BAUD = 0x99;
250         *R_SERIAL3_TR_CTRL = 0x40;
251 #endif
252
253         setup_normal_output_buffer();
254
255         makecrc();
256
257         __asm__ volatile ("move $vr,%0" : "=rm" (revision));
258         if (revision < 10)
259         {
260                 puts("You need an ETRAX 100LX to run linux 2.6\n");
261                 while(1);
262         }
263
264         puts("Uncompressing Linux...\n");
265         gunzip();
266         puts("Done. Now booting the kernel.\n");
267 }