Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / nios2 / boot / compressed / misc.c
1 /*
2  * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
3  *
4  * This is a collection of several routines from gzip-1.0.3
5  * adapted for Linux.
6  *
7  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8  *
9  * Adapted for SH by Stuart Menefy, Aug 1999
10  *
11  * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
12  *
13  * Based on arch/sh/boot/compressed/misc.c
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27  *
28  */
29
30 #include <linux/string.h>
31
32 /*
33  * gzip declarations
34  */
35 #define OF(args)  args
36 #define STATIC static
37
38 #undef memset
39 #undef memcpy
40 #define memzero(s, n)           memset((s), 0, (n))
41
42 typedef unsigned char  uch;
43 typedef unsigned short ush;
44 typedef unsigned long  ulg;
45 #define WSIZE 0x8000            /* Window size must be at least 32k, */
46                                 /* and a power of two */
47
48 static uch *inbuf;              /* input buffer */
49 static uch window[WSIZE];       /* Sliding window buffer */
50
51 static unsigned insize; /* valid bytes in inbuf */
52 static unsigned inptr;  /* index of next byte to be processed in inbuf */
53 static unsigned outcnt; /* bytes in output buffer */
54
55 /* gzip flag byte */
56 #define ASCII_FLAG      0x01 /* bit 0 set: file probably ASCII text */
57 #define CONTINUATION    0x02 /* bit 1 set: continuation of multi-part gzip
58                                 file */
59 #define EXTRA_FIELD     0x04 /* bit 2 set: extra field present */
60 #define ORIG_NAME       0x08 /* bit 3 set: original file name present */
61 #define COMMENT         0x10 /* bit 4 set: file comment present */
62 #define ENCRYPTED       0x20 /* bit 5 set: file is encrypted */
63 #define RESERVED        0xC0 /* bit 6,7:   reserved */
64
65 #define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
66
67 #ifdef DEBUG
68 #  define Assert(cond, msg) {if (!(cond)) error(msg); }
69 #  define Trace(x) fprintf x
70 #  define Tracev(x) {if (verbose) fprintf x ; }
71 #  define Tracevv(x) {if (verbose > 1) fprintf x ; }
72 #  define Tracec(c, x) {if (verbose && (c)) fprintf x ; }
73 #  define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; }
74 #else
75 #  define Assert(cond, msg)
76 #  define Trace(x)
77 #  define Tracev(x)
78 #  define Tracevv(x)
79 #  define Tracec(c, x)
80 #  define Tracecv(c, x)
81 #endif
82 static int  fill_inbuf(void);
83 static void flush_window(void);
84 static void error(char *m);
85
86 extern char input_data[];
87 extern int input_len;
88
89 static long bytes_out;
90 static uch *output_data;
91 static unsigned long output_ptr;
92
93 #include "console.c"
94
95 static void error(char *m);
96
97 int puts(const char *);
98
99 extern int _end;
100 static unsigned long free_mem_ptr;
101 static unsigned long free_mem_end_ptr;
102
103 #define HEAP_SIZE                       0x10000
104
105 #include "../../../../lib/inflate.c"
106
107 void *memset(void *s, int c, size_t n)
108 {
109         int i;
110         char *ss = (char *)s;
111
112         for (i = 0; i < n; i++)
113                 ss[i] = c;
114         return s;
115 }
116
117 void *memcpy(void *__dest, __const void *__src, size_t __n)
118 {
119         int i;
120         char *d = (char *)__dest, *s = (char *)__src;
121
122         for (i = 0; i < __n; i++)
123                 d[i] = s[i];
124         return __dest;
125 }
126
127 /*
128  * Fill the input buffer. This is called only when the buffer is empty
129  * and at least one byte is really needed.
130  */
131 static int fill_inbuf(void)
132 {
133         if (insize != 0)
134                 error("ran out of input data");
135
136         inbuf = input_data;
137         insize = input_len;
138         inptr = 1;
139         return inbuf[0];
140 }
141
142 /*
143  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
144  * (Used for the decompressed data only.)
145  */
146 static void flush_window(void)
147 {
148         ulg c = crc;    /* temporary variable */
149         unsigned n;
150         uch *in, *out, ch;
151
152         in = window;
153         out = &output_data[output_ptr];
154         for (n = 0; n < outcnt; n++) {
155                 ch = *out++ = *in++;
156                 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
157         }
158         crc = c;
159         bytes_out += (ulg)outcnt;
160         output_ptr += (ulg)outcnt;
161         outcnt = 0;
162 }
163
164 static void error(char *x)
165 {
166         puts("\nERROR\n");
167         puts(x);
168         puts("\n\n -- System halted");
169
170         while (1)       /* Halt */
171                 ;
172 }
173
174 void decompress_kernel(void)
175 {
176         output_data = (void *) (CONFIG_NIOS2_MEM_BASE |
177                                 CONFIG_NIOS2_KERNEL_REGION_BASE);
178         output_ptr = 0;
179         free_mem_ptr = (unsigned long)&_end;
180         free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
181
182         console_init();
183         makecrc();
184         puts("Uncompressing Linux... ");
185         gunzip();
186         puts("Ok, booting the kernel.\n");
187 }