18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * This is a collection of several routines from gzip-1.0.3
68c2ecf20Sopenharmony_ci * adapted for Linux.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * Adapted for SH by Stuart Menefy, Aug 1999
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * Based on arch/sh/boot/compressed/misc.c
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/string.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * gzip declarations
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci#define OF(args)  args
238c2ecf20Sopenharmony_ci#define STATIC static
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#undef memset
268c2ecf20Sopenharmony_ci#undef memcpy
278c2ecf20Sopenharmony_ci#define memzero(s, n)		memset((s), 0, (n))
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_citypedef unsigned char  uch;
308c2ecf20Sopenharmony_citypedef unsigned short ush;
318c2ecf20Sopenharmony_citypedef unsigned long  ulg;
328c2ecf20Sopenharmony_ci#define WSIZE 0x8000		/* Window size must be at least 32k, */
338c2ecf20Sopenharmony_ci				/* and a power of two */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic uch *inbuf;		/* input buffer */
368c2ecf20Sopenharmony_cistatic uch window[WSIZE];	/* Sliding window buffer */
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic unsigned insize;	/* valid bytes in inbuf */
398c2ecf20Sopenharmony_cistatic unsigned inptr;	/* index of next byte to be processed in inbuf */
408c2ecf20Sopenharmony_cistatic unsigned outcnt;	/* bytes in output buffer */
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/* gzip flag byte */
438c2ecf20Sopenharmony_ci#define ASCII_FLAG	0x01 /* bit 0 set: file probably ASCII text */
448c2ecf20Sopenharmony_ci#define CONTINUATION	0x02 /* bit 1 set: continuation of multi-part gzip
458c2ecf20Sopenharmony_ci				file */
468c2ecf20Sopenharmony_ci#define EXTRA_FIELD	0x04 /* bit 2 set: extra field present */
478c2ecf20Sopenharmony_ci#define ORIG_NAME	0x08 /* bit 3 set: original file name present */
488c2ecf20Sopenharmony_ci#define COMMENT		0x10 /* bit 4 set: file comment present */
498c2ecf20Sopenharmony_ci#define ENCRYPTED	0x20 /* bit 5 set: file is encrypted */
508c2ecf20Sopenharmony_ci#define RESERVED	0xC0 /* bit 6,7:   reserved */
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#ifdef DEBUG
558c2ecf20Sopenharmony_ci#  define Assert(cond, msg) {if (!(cond)) error(msg); }
568c2ecf20Sopenharmony_ci#  define Trace(x) fprintf x
578c2ecf20Sopenharmony_ci#  define Tracev(x) {if (verbose) fprintf x ; }
588c2ecf20Sopenharmony_ci#  define Tracevv(x) {if (verbose > 1) fprintf x ; }
598c2ecf20Sopenharmony_ci#  define Tracec(c, x) {if (verbose && (c)) fprintf x ; }
608c2ecf20Sopenharmony_ci#  define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; }
618c2ecf20Sopenharmony_ci#else
628c2ecf20Sopenharmony_ci#  define Assert(cond, msg)
638c2ecf20Sopenharmony_ci#  define Trace(x)
648c2ecf20Sopenharmony_ci#  define Tracev(x)
658c2ecf20Sopenharmony_ci#  define Tracevv(x)
668c2ecf20Sopenharmony_ci#  define Tracec(c, x)
678c2ecf20Sopenharmony_ci#  define Tracecv(c, x)
688c2ecf20Sopenharmony_ci#endif
698c2ecf20Sopenharmony_cistatic int  fill_inbuf(void);
708c2ecf20Sopenharmony_cistatic void flush_window(void);
718c2ecf20Sopenharmony_cistatic void error(char *m);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciextern char input_data[];
748c2ecf20Sopenharmony_ciextern int input_len;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic long bytes_out;
778c2ecf20Sopenharmony_cistatic uch *output_data;
788c2ecf20Sopenharmony_cistatic unsigned long output_ptr;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci#include "console.c"
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistatic void error(char *m);
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ciint puts(const char *);
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ciextern int _end;
878c2ecf20Sopenharmony_cistatic unsigned long free_mem_ptr;
888c2ecf20Sopenharmony_cistatic unsigned long free_mem_end_ptr;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci#define HEAP_SIZE			0x10000
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci#include "../../../../lib/inflate.c"
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_civoid *memset(void *s, int c, size_t n)
958c2ecf20Sopenharmony_ci{
968c2ecf20Sopenharmony_ci	int i;
978c2ecf20Sopenharmony_ci	char *ss = (char *)s;
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	for (i = 0; i < n; i++)
1008c2ecf20Sopenharmony_ci		ss[i] = c;
1018c2ecf20Sopenharmony_ci	return s;
1028c2ecf20Sopenharmony_ci}
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_civoid *memcpy(void *__dest, __const void *__src, size_t __n)
1058c2ecf20Sopenharmony_ci{
1068c2ecf20Sopenharmony_ci	int i;
1078c2ecf20Sopenharmony_ci	char *d = (char *)__dest, *s = (char *)__src;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	for (i = 0; i < __n; i++)
1108c2ecf20Sopenharmony_ci		d[i] = s[i];
1118c2ecf20Sopenharmony_ci	return __dest;
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci/*
1158c2ecf20Sopenharmony_ci * Fill the input buffer. This is called only when the buffer is empty
1168c2ecf20Sopenharmony_ci * and at least one byte is really needed.
1178c2ecf20Sopenharmony_ci */
1188c2ecf20Sopenharmony_cistatic int fill_inbuf(void)
1198c2ecf20Sopenharmony_ci{
1208c2ecf20Sopenharmony_ci	if (insize != 0)
1218c2ecf20Sopenharmony_ci		error("ran out of input data");
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	inbuf = input_data;
1248c2ecf20Sopenharmony_ci	insize = input_len;
1258c2ecf20Sopenharmony_ci	inptr = 1;
1268c2ecf20Sopenharmony_ci	return inbuf[0];
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci/*
1308c2ecf20Sopenharmony_ci * Write the output window window[0..outcnt-1] and update crc and bytes_out.
1318c2ecf20Sopenharmony_ci * (Used for the decompressed data only.)
1328c2ecf20Sopenharmony_ci */
1338c2ecf20Sopenharmony_cistatic void flush_window(void)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	ulg c = crc;	/* temporary variable */
1368c2ecf20Sopenharmony_ci	unsigned n;
1378c2ecf20Sopenharmony_ci	uch *in, *out, ch;
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	in = window;
1408c2ecf20Sopenharmony_ci	out = &output_data[output_ptr];
1418c2ecf20Sopenharmony_ci	for (n = 0; n < outcnt; n++) {
1428c2ecf20Sopenharmony_ci		ch = *out++ = *in++;
1438c2ecf20Sopenharmony_ci		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
1448c2ecf20Sopenharmony_ci	}
1458c2ecf20Sopenharmony_ci	crc = c;
1468c2ecf20Sopenharmony_ci	bytes_out += (ulg)outcnt;
1478c2ecf20Sopenharmony_ci	output_ptr += (ulg)outcnt;
1488c2ecf20Sopenharmony_ci	outcnt = 0;
1498c2ecf20Sopenharmony_ci}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic void error(char *x)
1528c2ecf20Sopenharmony_ci{
1538c2ecf20Sopenharmony_ci	puts("\nERROR\n");
1548c2ecf20Sopenharmony_ci	puts(x);
1558c2ecf20Sopenharmony_ci	puts("\n\n -- System halted");
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	while (1)	/* Halt */
1588c2ecf20Sopenharmony_ci		;
1598c2ecf20Sopenharmony_ci}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_civoid decompress_kernel(void)
1628c2ecf20Sopenharmony_ci{
1638c2ecf20Sopenharmony_ci	output_data = (void *) (CONFIG_NIOS2_MEM_BASE |
1648c2ecf20Sopenharmony_ci				CONFIG_NIOS2_KERNEL_REGION_BASE);
1658c2ecf20Sopenharmony_ci	output_ptr = 0;
1668c2ecf20Sopenharmony_ci	free_mem_ptr = (unsigned long)&_end;
1678c2ecf20Sopenharmony_ci	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	console_init();
1708c2ecf20Sopenharmony_ci	makecrc();
1718c2ecf20Sopenharmony_ci	puts("Uncompressing Linux... ");
1728c2ecf20Sopenharmony_ci	gunzip();
1738c2ecf20Sopenharmony_ci	puts("Ok, booting the kernel.\n");
1748c2ecf20Sopenharmony_ci}
175