aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/boot/compressed/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boot/compressed/misc.c')
-rw-r--r--arch/arm/boot/compressed/misc.c129
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
19unsigned int __machine_arch_type; 19unsigned 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
59static 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
53static void icedcc_putc(int ch) 70static 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
89static void putstr(const char *ptr) 105static 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
194typedef unsigned char uch;
195typedef unsigned short ush;
196typedef unsigned long ulg;
197
198#define WSIZE 0x8000 /* Window size must be at least 32k, */
199 /* and a power of two */
200
201static uch *inbuf; /* input buffer */
202static uch window[WSIZE]; /* Sliding window buffer */
203
204static unsigned insize; /* valid bytes in inbuf */
205static unsigned inptr; /* index of next byte to be processed in inbuf */
206static 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
236static int fill_inbuf(void);
237static void flush_window(void);
238static void error(char *m); 226static void error(char *m);
239 227
240extern char input_data[]; 228extern char input_data[];
241extern char input_data_end[]; 229extern char input_data_end[];
242 230
243static uch *output_data; 231static unsigned char *output_data;
244static ulg output_ptr; 232static unsigned long output_ptr;
245static ulg bytes_out;
246 233
247static void error(char *m); 234static void error(char *m);
248 235
249static void putstr(const char *); 236static void putstr(const char *);
250 237
251extern int end; 238static unsigned long free_mem_ptr;
252static ulg free_mem_ptr; 239static unsigned long free_mem_end_ptr;
253static 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 */
267int 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 */
283void 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
270asmlinkage void __div0(void)
271{
272 error("Attempting division by 0!");
273}
274
317#ifndef STANDALONE_DEBUG 275#ifndef STANDALONE_DEBUG
318 276
319ulg 277unsigned long
320decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, 278decompress_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