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