diff options
author | David S. Miller <davem@davemloft.net> | 2010-01-23 03:31:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-23 03:31:06 -0500 |
commit | 51c24aaacaea90c8e87f1dec75a2ac7622b593f8 (patch) | |
tree | 9f54936c87764bef75e97395cb56b7d1e0df24c6 /arch/arm/boot/compressed/misc.c | |
parent | 4276e47e2d1c85a2477caf0d22b91c4f2377fba8 (diff) | |
parent | 6be325719b3e54624397e413efd4b33a997e55a3 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'arch/arm/boot/compressed/misc.c')
-rw-r--r-- | arch/arm/boot/compressed/misc.c | 129 |
1 files changed, 46 insertions, 83 deletions
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 17153b54613b..56a0d116d271 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c | |||
@@ -18,10 +18,15 @@ | |||
18 | 18 | ||
19 | unsigned int __machine_arch_type; | 19 | unsigned int __machine_arch_type; |
20 | 20 | ||
21 | #define _LINUX_STRING_H_ | ||
22 | |||
21 | #include <linux/compiler.h> /* for inline */ | 23 | #include <linux/compiler.h> /* for inline */ |
22 | #include <linux/types.h> /* for size_t */ | 24 | #include <linux/types.h> /* for size_t */ |
23 | #include <linux/stddef.h> /* for NULL */ | 25 | #include <linux/stddef.h> /* for NULL */ |
24 | #include <asm/string.h> | 26 | #include <asm/string.h> |
27 | #include <linux/linkage.h> | ||
28 | |||
29 | #include <asm/unaligned.h> | ||
25 | 30 | ||
26 | #ifdef STANDALONE_DEBUG | 31 | #ifdef STANDALONE_DEBUG |
27 | #define putstr printf | 32 | #define putstr printf |
@@ -48,6 +53,18 @@ static void icedcc_putc(int ch) | |||
48 | 53 | ||
49 | asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); | 54 | asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); |
50 | } | 55 | } |
56 | |||
57 | #elif defined(CONFIG_CPU_V7) | ||
58 | |||
59 | static void icedcc_putc(int ch) | ||
60 | { | ||
61 | asm( | ||
62 | "wait: mrc p14, 0, pc, c0, c1, 0 \n\ | ||
63 | bcs wait \n\ | ||
64 | mcr p14, 0, %0, c0, c5, 0 " | ||
65 | : : "r" (ch)); | ||
66 | } | ||
67 | |||
51 | #elif defined(CONFIG_CPU_XSCALE) | 68 | #elif defined(CONFIG_CPU_XSCALE) |
52 | 69 | ||
53 | static void icedcc_putc(int ch) | 70 | static void icedcc_putc(int ch) |
@@ -83,7 +100,6 @@ static void icedcc_putc(int ch) | |||
83 | #endif | 100 | #endif |
84 | 101 | ||
85 | #define putc(ch) icedcc_putc(ch) | 102 | #define putc(ch) icedcc_putc(ch) |
86 | #define flush() do { } while (0) | ||
87 | #endif | 103 | #endif |
88 | 104 | ||
89 | static void putstr(const char *ptr) | 105 | static void putstr(const char *ptr) |
@@ -188,34 +204,8 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, | |||
188 | /* | 204 | /* |
189 | * gzip delarations | 205 | * gzip delarations |
190 | */ | 206 | */ |
191 | #define OF(args) args | ||
192 | #define STATIC static | 207 | #define STATIC static |
193 | 208 | ||
194 | typedef unsigned char uch; | ||
195 | typedef unsigned short ush; | ||
196 | typedef unsigned long ulg; | ||
197 | |||
198 | #define WSIZE 0x8000 /* Window size must be at least 32k, */ | ||
199 | /* and a power of two */ | ||
200 | |||
201 | static uch *inbuf; /* input buffer */ | ||
202 | static uch window[WSIZE]; /* Sliding window buffer */ | ||
203 | |||
204 | static unsigned insize; /* valid bytes in inbuf */ | ||
205 | static unsigned inptr; /* index of next byte to be processed in inbuf */ | ||
206 | static unsigned outcnt; /* bytes in output buffer */ | ||
207 | |||
208 | /* gzip flag byte */ | ||
209 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ | ||
210 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ | ||
211 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ | ||
212 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ | ||
213 | #define COMMENT 0x10 /* bit 4 set: file comment present */ | ||
214 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | ||
215 | #define RESERVED 0xC0 /* bit 6,7: reserved */ | ||
216 | |||
217 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) | ||
218 | |||
219 | /* Diagnostic functions */ | 209 | /* Diagnostic functions */ |
220 | #ifdef DEBUG | 210 | #ifdef DEBUG |
221 | # define Assert(cond,msg) {if(!(cond)) error(msg);} | 211 | # define Assert(cond,msg) {if(!(cond)) error(msg);} |
@@ -233,24 +223,20 @@ static unsigned outcnt; /* bytes in output buffer */ | |||
233 | # define Tracecv(c,x) | 223 | # define Tracecv(c,x) |
234 | #endif | 224 | #endif |
235 | 225 | ||
236 | static int fill_inbuf(void); | ||
237 | static void flush_window(void); | ||
238 | static void error(char *m); | 226 | static void error(char *m); |
239 | 227 | ||
240 | extern char input_data[]; | 228 | extern char input_data[]; |
241 | extern char input_data_end[]; | 229 | extern char input_data_end[]; |
242 | 230 | ||
243 | static uch *output_data; | 231 | static unsigned char *output_data; |
244 | static ulg output_ptr; | 232 | static unsigned long output_ptr; |
245 | static ulg bytes_out; | ||
246 | 233 | ||
247 | static void error(char *m); | 234 | static void error(char *m); |
248 | 235 | ||
249 | static void putstr(const char *); | 236 | static void putstr(const char *); |
250 | 237 | ||
251 | extern int end; | 238 | static unsigned long free_mem_ptr; |
252 | static ulg free_mem_ptr; | 239 | static unsigned long free_mem_end_ptr; |
253 | static ulg free_mem_end_ptr; | ||
254 | 240 | ||
255 | #ifdef STANDALONE_DEBUG | 241 | #ifdef STANDALONE_DEBUG |
256 | #define NO_INFLATE_MALLOC | 242 | #define NO_INFLATE_MALLOC |
@@ -258,46 +244,13 @@ static ulg free_mem_end_ptr; | |||
258 | 244 | ||
259 | #define ARCH_HAS_DECOMP_WDOG | 245 | #define ARCH_HAS_DECOMP_WDOG |
260 | 246 | ||
261 | #include "../../../../lib/inflate.c" | 247 | #ifdef CONFIG_KERNEL_GZIP |
262 | 248 | #include "../../../../lib/decompress_inflate.c" | |
263 | /* =========================================================================== | 249 | #endif |
264 | * Fill the input buffer. This is called only when the buffer is empty | ||
265 | * and at least one byte is really needed. | ||
266 | */ | ||
267 | int fill_inbuf(void) | ||
268 | { | ||
269 | if (insize != 0) | ||
270 | error("ran out of input data"); | ||
271 | |||
272 | inbuf = input_data; | ||
273 | insize = &input_data_end[0] - &input_data[0]; | ||
274 | |||
275 | inptr = 1; | ||
276 | return inbuf[0]; | ||
277 | } | ||
278 | 250 | ||
279 | /* =========================================================================== | 251 | #ifdef CONFIG_KERNEL_LZO |
280 | * Write the output window window[0..outcnt-1] and update crc and bytes_out. | 252 | #include "../../../../lib/decompress_unlzo.c" |
281 | * (Used for the decompressed data only.) | 253 | #endif |
282 | */ | ||
283 | void flush_window(void) | ||
284 | { | ||
285 | ulg c = crc; | ||
286 | unsigned n; | ||
287 | uch *in, *out, ch; | ||
288 | |||
289 | in = window; | ||
290 | out = &output_data[output_ptr]; | ||
291 | for (n = 0; n < outcnt; n++) { | ||
292 | ch = *out++ = *in++; | ||
293 | c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | ||
294 | } | ||
295 | crc = c; | ||
296 | bytes_out += (ulg)outcnt; | ||
297 | output_ptr += (ulg)outcnt; | ||
298 | outcnt = 0; | ||
299 | putstr("."); | ||
300 | } | ||
301 | 254 | ||
302 | #ifndef arch_error | 255 | #ifndef arch_error |
303 | #define arch_error(x) | 256 | #define arch_error(x) |
@@ -314,22 +267,33 @@ static void error(char *x) | |||
314 | while(1); /* Halt */ | 267 | while(1); /* Halt */ |
315 | } | 268 | } |
316 | 269 | ||
270 | asmlinkage void __div0(void) | ||
271 | { | ||
272 | error("Attempting division by 0!"); | ||
273 | } | ||
274 | |||
317 | #ifndef STANDALONE_DEBUG | 275 | #ifndef STANDALONE_DEBUG |
318 | 276 | ||
319 | ulg | 277 | unsigned long |
320 | decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, | 278 | decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, |
321 | int arch_id) | 279 | unsigned long free_mem_ptr_end_p, |
280 | int arch_id) | ||
322 | { | 281 | { |
323 | output_data = (uch *)output_start; /* Points to kernel start */ | 282 | unsigned char *tmp; |
283 | |||
284 | output_data = (unsigned char *)output_start; | ||
324 | free_mem_ptr = free_mem_ptr_p; | 285 | free_mem_ptr = free_mem_ptr_p; |
325 | free_mem_end_ptr = free_mem_ptr_end_p; | 286 | free_mem_end_ptr = free_mem_ptr_end_p; |
326 | __machine_arch_type = arch_id; | 287 | __machine_arch_type = arch_id; |
327 | 288 | ||
328 | arch_decomp_setup(); | 289 | arch_decomp_setup(); |
329 | 290 | ||
330 | makecrc(); | 291 | tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); |
292 | output_ptr = get_unaligned_le32(tmp); | ||
293 | |||
331 | putstr("Uncompressing Linux..."); | 294 | putstr("Uncompressing Linux..."); |
332 | gunzip(); | 295 | decompress(input_data, input_data_end - input_data, |
296 | NULL, NULL, output_data, NULL, error); | ||
333 | putstr(" done, booting the kernel.\n"); | 297 | putstr(" done, booting the kernel.\n"); |
334 | return output_ptr; | 298 | return output_ptr; |
335 | } | 299 | } |
@@ -341,11 +305,10 @@ int main() | |||
341 | { | 305 | { |
342 | output_data = output_buffer; | 306 | output_data = output_buffer; |
343 | 307 | ||
344 | makecrc(); | ||
345 | putstr("Uncompressing Linux..."); | 308 | putstr("Uncompressing Linux..."); |
346 | gunzip(); | 309 | decompress(input_data, input_data_end - input_data, |
310 | NULL, NULL, output_data, NULL, error); | ||
347 | putstr("done.\n"); | 311 | putstr("done.\n"); |
348 | return 0; | 312 | return 0; |
349 | } | 313 | } |
350 | #endif | 314 | #endif |
351 | |||