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