xref: /openbmc/linux/arch/sh/boot/compressed/misc.c (revision 50cfa79d)
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