162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw> 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This is a collection of several routines from gzip-1.0.3 662306a36Sopenharmony_ci * adapted for Linux. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Adapted for SH by Stuart Menefy, Aug 1999 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * Based on arch/sh/boot/compressed/misc.c 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <linux/string.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* 2062306a36Sopenharmony_ci * gzip declarations 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ci#define OF(args) args 2362306a36Sopenharmony_ci#define STATIC static 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#undef memset 2662306a36Sopenharmony_ci#undef memcpy 2762306a36Sopenharmony_ci#define memzero(s, n) memset((s), 0, (n)) 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_citypedef unsigned char uch; 3062306a36Sopenharmony_citypedef unsigned short ush; 3162306a36Sopenharmony_citypedef unsigned long ulg; 3262306a36Sopenharmony_ci#define WSIZE 0x8000 /* Window size must be at least 32k, */ 3362306a36Sopenharmony_ci /* and a power of two */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic uch *inbuf; /* input buffer */ 3662306a36Sopenharmony_cistatic uch window[WSIZE]; /* Sliding window buffer */ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic unsigned insize; /* valid bytes in inbuf */ 3962306a36Sopenharmony_cistatic unsigned inptr; /* index of next byte to be processed in inbuf */ 4062306a36Sopenharmony_cistatic unsigned outcnt; /* bytes in output buffer */ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* gzip flag byte */ 4362306a36Sopenharmony_ci#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ 4462306a36Sopenharmony_ci#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip 4562306a36Sopenharmony_ci file */ 4662306a36Sopenharmony_ci#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 4762306a36Sopenharmony_ci#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 4862306a36Sopenharmony_ci#define COMMENT 0x10 /* bit 4 set: file comment present */ 4962306a36Sopenharmony_ci#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ 5062306a36Sopenharmony_ci#define RESERVED 0xC0 /* bit 6,7: reserved */ 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#ifdef DEBUG 5562306a36Sopenharmony_ci# define Assert(cond, msg) {if (!(cond)) error(msg); } 5662306a36Sopenharmony_ci# define Trace(x) fprintf x 5762306a36Sopenharmony_ci# define Tracev(x) {if (verbose) fprintf x ; } 5862306a36Sopenharmony_ci# define Tracevv(x) {if (verbose > 1) fprintf x ; } 5962306a36Sopenharmony_ci# define Tracec(c, x) {if (verbose && (c)) fprintf x ; } 6062306a36Sopenharmony_ci# define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; } 6162306a36Sopenharmony_ci#else 6262306a36Sopenharmony_ci# define Assert(cond, msg) 6362306a36Sopenharmony_ci# define Trace(x) 6462306a36Sopenharmony_ci# define Tracev(x) 6562306a36Sopenharmony_ci# define Tracevv(x) 6662306a36Sopenharmony_ci# define Tracec(c, x) 6762306a36Sopenharmony_ci# define Tracecv(c, x) 6862306a36Sopenharmony_ci#endif 6962306a36Sopenharmony_cistatic int fill_inbuf(void); 7062306a36Sopenharmony_cistatic void flush_window(void); 7162306a36Sopenharmony_cistatic void error(char *m); 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciextern char input_data[]; 7462306a36Sopenharmony_ciextern int input_len; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic long bytes_out; 7762306a36Sopenharmony_cistatic uch *output_data; 7862306a36Sopenharmony_cistatic unsigned long output_ptr; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#include "console.c" 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic void error(char *m); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ciint puts(const char *); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciextern int _end; 8762306a36Sopenharmony_cistatic unsigned long free_mem_ptr; 8862306a36Sopenharmony_cistatic unsigned long free_mem_end_ptr; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci#define HEAP_SIZE 0x10000 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#include "../../../../lib/inflate.c" 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_civoid *memset(void *s, int c, size_t n) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci int i; 9762306a36Sopenharmony_ci char *ss = (char *)s; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci for (i = 0; i < n; i++) 10062306a36Sopenharmony_ci ss[i] = c; 10162306a36Sopenharmony_ci return s; 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_civoid *memcpy(void *__dest, __const void *__src, size_t __n) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci int i; 10762306a36Sopenharmony_ci char *d = (char *)__dest, *s = (char *)__src; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci for (i = 0; i < __n; i++) 11062306a36Sopenharmony_ci d[i] = s[i]; 11162306a36Sopenharmony_ci return __dest; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/* 11562306a36Sopenharmony_ci * Fill the input buffer. This is called only when the buffer is empty 11662306a36Sopenharmony_ci * and at least one byte is really needed. 11762306a36Sopenharmony_ci */ 11862306a36Sopenharmony_cistatic int fill_inbuf(void) 11962306a36Sopenharmony_ci{ 12062306a36Sopenharmony_ci if (insize != 0) 12162306a36Sopenharmony_ci error("ran out of input data"); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci inbuf = input_data; 12462306a36Sopenharmony_ci insize = input_len; 12562306a36Sopenharmony_ci inptr = 1; 12662306a36Sopenharmony_ci return inbuf[0]; 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci/* 13062306a36Sopenharmony_ci * Write the output window window[0..outcnt-1] and update crc and bytes_out. 13162306a36Sopenharmony_ci * (Used for the decompressed data only.) 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_cistatic void flush_window(void) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci ulg c = crc; /* temporary variable */ 13662306a36Sopenharmony_ci unsigned n; 13762306a36Sopenharmony_ci uch *in, *out, ch; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci in = window; 14062306a36Sopenharmony_ci out = &output_data[output_ptr]; 14162306a36Sopenharmony_ci for (n = 0; n < outcnt; n++) { 14262306a36Sopenharmony_ci ch = *out++ = *in++; 14362306a36Sopenharmony_ci c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci crc = c; 14662306a36Sopenharmony_ci bytes_out += (ulg)outcnt; 14762306a36Sopenharmony_ci output_ptr += (ulg)outcnt; 14862306a36Sopenharmony_ci outcnt = 0; 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic void error(char *x) 15262306a36Sopenharmony_ci{ 15362306a36Sopenharmony_ci puts("\nERROR\n"); 15462306a36Sopenharmony_ci puts(x); 15562306a36Sopenharmony_ci puts("\n\n -- System halted"); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci while (1) /* Halt */ 15862306a36Sopenharmony_ci ; 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_civoid decompress_kernel(void) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci output_data = (void *) (CONFIG_NIOS2_MEM_BASE | 16462306a36Sopenharmony_ci CONFIG_NIOS2_KERNEL_REGION_BASE); 16562306a36Sopenharmony_ci output_ptr = 0; 16662306a36Sopenharmony_ci free_mem_ptr = (unsigned long)&_end; 16762306a36Sopenharmony_ci free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci console_init(); 17062306a36Sopenharmony_ci makecrc(); 17162306a36Sopenharmony_ci puts("Uncompressing Linux... "); 17262306a36Sopenharmony_ci gunzip(); 17362306a36Sopenharmony_ci puts("Ok, booting the kernel.\n"); 17462306a36Sopenharmony_ci} 175