xref: /OK3568_Linux_fs/kernel/arch/nios2/boot/compressed/misc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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