diff options
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 @@ unsigned int __machine_arch_type; +#define _LINUX_STRING_H_ + #include <linux/compiler.h> /* for inline */ #include <linux/types.h> /* for size_t */ #include <linux/stddef.h> /* for NULL */ #include <asm/string.h> +#include <linux/linkage.h> + +#include <asm/unaligned.h> #ifdef STANDALONE_DEBUG #define putstr printf @@ -48,6 +53,18 @@ static void icedcc_putc(int ch) asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); } + +#elif defined(CONFIG_CPU_V7) + +static void icedcc_putc(int ch) +{ + asm( + "wait: mrc p14, 0, pc, c0, c1, 0 \n\ + bcs wait \n\ + mcr p14, 0, %0, c0, c5, 0 " + : : "r" (ch)); +} + #elif defined(CONFIG_CPU_XSCALE) static void icedcc_putc(int ch) @@ -83,7 +100,6 @@ static void icedcc_putc(int ch) #endif #define putc(ch) icedcc_putc(ch) -#define flush() do { } while (0) #endif static void putstr(const char *ptr) @@ -188,34 +204,8 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, /* * gzip delarations */ -#define OF(args) args #define STATIC static -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - /* Diagnostic functions */ #ifdef DEBUG # define Assert(cond,msg) {if(!(cond)) error(msg);} @@ -233,24 +223,20 @@ static unsigned outcnt; /* bytes in output buffer */ # define Tracecv(c,x) #endif -static int fill_inbuf(void); -static void flush_window(void); static void error(char *m); extern char input_data[]; extern char input_data_end[]; -static uch *output_data; -static ulg output_ptr; -static ulg bytes_out; +static unsigned char *output_data; +static unsigned long output_ptr; static void error(char *m); static void putstr(const char *); -extern int end; -static ulg free_mem_ptr; -static ulg free_mem_end_ptr; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; #ifdef STANDALONE_DEBUG #define NO_INFLATE_MALLOC @@ -258,46 +244,13 @@ static ulg free_mem_end_ptr; #define ARCH_HAS_DECOMP_WDOG -#include "../../../../lib/inflate.c" - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -int fill_inbuf(void) -{ - if (insize != 0) - error("ran out of input data"); - - inbuf = input_data; - insize = &input_data_end[0] - &input_data[0]; - - inptr = 1; - return inbuf[0]; -} +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -void flush_window(void) -{ - ulg c = crc; - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; - putstr("."); -} +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif #ifndef arch_error #define arch_error(x) @@ -314,22 +267,33 @@ static void error(char *x) while(1); /* Halt */ } +asmlinkage void __div0(void) +{ + error("Attempting division by 0!"); +} + #ifndef STANDALONE_DEBUG -ulg -decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, - int arch_id) +unsigned long +decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, + unsigned long free_mem_ptr_end_p, + int arch_id) { - output_data = (uch *)output_start; /* Points to kernel start */ + unsigned char *tmp; + + output_data = (unsigned char *)output_start; free_mem_ptr = free_mem_ptr_p; free_mem_end_ptr = free_mem_ptr_end_p; __machine_arch_type = arch_id; arch_decomp_setup(); - makecrc(); + tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); + output_ptr = get_unaligned_le32(tmp); + putstr("Uncompressing Linux..."); - gunzip(); + decompress(input_data, input_data_end - input_data, + NULL, NULL, output_data, NULL, error); putstr(" done, booting the kernel.\n"); return output_ptr; } @@ -341,11 +305,10 @@ int main() { output_data = output_buffer; - makecrc(); putstr("Uncompressing Linux..."); - gunzip(); + decompress(input_data, input_data_end - input_data, + NULL, NULL, output_data, NULL, error); putstr("done.\n"); return 0; } #endif - |