159f00296SPaul Mundt /* 259f00296SPaul Mundt * arch/sh/boot/compressed/misc.c 359f00296SPaul Mundt * 459f00296SPaul Mundt * This is a collection of several routines from gzip-1.0.3 559f00296SPaul Mundt * adapted for Linux. 659f00296SPaul Mundt * 759f00296SPaul Mundt * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 859f00296SPaul Mundt * 959f00296SPaul Mundt * Adapted for SH by Stuart Menefy, Aug 1999 1059f00296SPaul Mundt * 1159f00296SPaul Mundt * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000 1259f00296SPaul Mundt */ 1359f00296SPaul Mundt 1459f00296SPaul Mundt #include <asm/uaccess.h> 1559f00296SPaul Mundt #include <asm/addrspace.h> 1659f00296SPaul Mundt #include <asm/page.h> 1759f00296SPaul Mundt 1859f00296SPaul Mundt /* 1959f00296SPaul Mundt * gzip declarations 2059f00296SPaul Mundt */ 2159f00296SPaul Mundt 2259f00296SPaul Mundt #define STATIC static 2359f00296SPaul Mundt 2459f00296SPaul Mundt #undef memset 2559f00296SPaul Mundt #undef memcpy 2659f00296SPaul Mundt #define memzero(s, n) memset ((s), 0, (n)) 2759f00296SPaul Mundt 2859f00296SPaul Mundt /* cache.c */ 2959f00296SPaul Mundt #define CACHE_ENABLE 0 3059f00296SPaul Mundt #define CACHE_DISABLE 1 3159f00296SPaul Mundt int cache_control(unsigned int command); 3259f00296SPaul Mundt 3359f00296SPaul Mundt extern char input_data[]; 3459f00296SPaul Mundt extern int input_len; 3559f00296SPaul Mundt static unsigned char *output; 3659f00296SPaul Mundt 3759f00296SPaul Mundt static void error(char *m); 3859f00296SPaul Mundt 3959f00296SPaul Mundt int puts(const char *); 4059f00296SPaul Mundt 4159f00296SPaul Mundt extern int _text; /* Defined in vmlinux.lds.S */ 4259f00296SPaul Mundt extern int _end; 4359f00296SPaul Mundt static unsigned long free_mem_ptr; 4459f00296SPaul Mundt static unsigned long free_mem_end_ptr; 4559f00296SPaul Mundt 4659f00296SPaul Mundt #ifdef CONFIG_HAVE_KERNEL_BZIP2 4759f00296SPaul Mundt #define HEAP_SIZE 0x400000 4859f00296SPaul Mundt #else 4959f00296SPaul Mundt #define HEAP_SIZE 0x10000 5059f00296SPaul Mundt #endif 5159f00296SPaul Mundt 5259f00296SPaul Mundt #ifdef CONFIG_KERNEL_GZIP 5359f00296SPaul Mundt #include "../../../../lib/decompress_inflate.c" 5459f00296SPaul Mundt #endif 5559f00296SPaul Mundt 5659f00296SPaul Mundt #ifdef CONFIG_KERNEL_BZIP2 5759f00296SPaul Mundt #include "../../../../lib/decompress_bunzip2.c" 5859f00296SPaul Mundt #endif 5959f00296SPaul Mundt 6059f00296SPaul Mundt #ifdef CONFIG_KERNEL_LZMA 6159f00296SPaul Mundt #include "../../../../lib/decompress_unlzma.c" 6259f00296SPaul Mundt #endif 6359f00296SPaul Mundt 6450cfa79dSPaul Mundt #ifdef CONFIG_KERNEL_XZ 6550cfa79dSPaul Mundt #include "../../../../lib/decompress_unxz.c" 6650cfa79dSPaul Mundt #endif 6750cfa79dSPaul Mundt 68c7b16efbSPaul Mundt #ifdef CONFIG_KERNEL_LZO 69c7b16efbSPaul Mundt #include "../../../../lib/decompress_unlzo.c" 70c7b16efbSPaul Mundt #endif 71c7b16efbSPaul Mundt 7259f00296SPaul Mundt int puts(const char *s) 7359f00296SPaul Mundt { 7459f00296SPaul Mundt /* This should be updated to use the sh-sci routines */ 7559f00296SPaul Mundt return 0; 7659f00296SPaul Mundt } 7759f00296SPaul Mundt 7859f00296SPaul Mundt void* memset(void* s, int c, size_t n) 7959f00296SPaul Mundt { 8059f00296SPaul Mundt int i; 8159f00296SPaul Mundt char *ss = (char*)s; 8259f00296SPaul Mundt 8359f00296SPaul Mundt for (i=0;i<n;i++) ss[i] = c; 8459f00296SPaul Mundt return s; 8559f00296SPaul Mundt } 8659f00296SPaul Mundt 8759f00296SPaul Mundt void* memcpy(void* __dest, __const void* __src, 8859f00296SPaul Mundt size_t __n) 8959f00296SPaul Mundt { 9059f00296SPaul Mundt int i; 9159f00296SPaul Mundt char *d = (char *)__dest, *s = (char *)__src; 9259f00296SPaul Mundt 9359f00296SPaul Mundt for (i=0;i<__n;i++) d[i] = s[i]; 9459f00296SPaul Mundt return __dest; 9559f00296SPaul Mundt } 9659f00296SPaul Mundt 9759f00296SPaul Mundt static void error(char *x) 9859f00296SPaul Mundt { 9959f00296SPaul Mundt puts("\n\n"); 10059f00296SPaul Mundt puts(x); 10159f00296SPaul Mundt puts("\n\n -- System halted"); 10259f00296SPaul Mundt 10359f00296SPaul Mundt while(1); /* Halt */ 10459f00296SPaul Mundt } 10559f00296SPaul Mundt 10659f00296SPaul Mundt #ifdef CONFIG_SUPERH64 10759f00296SPaul Mundt #define stackalign 8 10859f00296SPaul Mundt #else 10959f00296SPaul Mundt #define stackalign 4 11059f00296SPaul Mundt #endif 11159f00296SPaul Mundt 11259f00296SPaul Mundt #define STACK_SIZE (4096) 11359f00296SPaul Mundt long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE]; 11459f00296SPaul Mundt long *stack_start = &user_stack[STACK_SIZE]; 11559f00296SPaul Mundt 11659f00296SPaul Mundt void decompress_kernel(void) 11759f00296SPaul Mundt { 11859f00296SPaul Mundt unsigned long output_addr; 11959f00296SPaul Mundt 120040f43e0SPaul Mundt #ifdef CONFIG_SUPERH64 121040f43e0SPaul Mundt output_addr = (CONFIG_MEMORY_START + 0x2000); 122040f43e0SPaul Mundt #else 1238bd642b1SMatt Fleming output_addr = __pa((unsigned long)&_text+PAGE_SIZE); 124d01447b3SPaul Mundt #if defined(CONFIG_29BIT) 12559f00296SPaul Mundt output_addr |= P2SEG; 12659f00296SPaul Mundt #endif 127040f43e0SPaul Mundt #endif 12859f00296SPaul Mundt 12959f00296SPaul Mundt output = (unsigned char *)output_addr; 13059f00296SPaul Mundt free_mem_ptr = (unsigned long)&_end; 13159f00296SPaul Mundt free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; 13259f00296SPaul Mundt 13359f00296SPaul Mundt puts("Uncompressing Linux... "); 13459f00296SPaul Mundt cache_control(CACHE_ENABLE); 13559f00296SPaul Mundt decompress(input_data, input_len, NULL, NULL, output, NULL, error); 13659f00296SPaul Mundt cache_control(CACHE_DISABLE); 13759f00296SPaul Mundt puts("Ok, booting the kernel.\n"); 13859f00296SPaul Mundt } 139