1/* 2 * misc.c 3 * 4 * $Id: misc.c,v 1.1.1.1 2008/10/15 03:26:00 james26_jang Exp $ 5 * 6 * This is a collection of several routines from gzip-1.0.3 7 * adapted for Linux. 8 * 9 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 10 * puts by Nick Holloway 1993, better puts by Martin Mares 1995 11 * adoptation for Linux/CRIS Axis Communications AB, 1999 12 * 13 */ 14 15/* where the piggybacked kernel image expects itself to live. 16 * it is the same adress we use when we network load an uncompressed 17 * image into DRAM, and it is the address the kernel is linked to live 18 * at by etrax100.ld. 19 */ 20 21#define KERNEL_LOAD_ADR 0x40004000 22 23#include <linux/config.h> 24 25#include <linux/types.h> 26#include <asm/svinto.h> 27 28/* 29 * gzip declarations 30 */ 31 32#define OF(args) args 33#define STATIC static 34 35void* memset(void* s, int c, size_t n); 36void* memcpy(void* __dest, __const void* __src, 37 size_t __n); 38 39#define memzero(s, n) memset ((s), 0, (n)) 40 41 42typedef unsigned char uch; 43typedef unsigned short ush; 44typedef unsigned long ulg; 45 46#define WSIZE 0x8000 /* Window size must be at least 32k, */ 47 /* and a power of two */ 48 49static uch *inbuf; /* input buffer */ 50static uch window[WSIZE]; /* Sliding window buffer */ 51 52unsigned inptr = 0; /* index of next byte to be processed in inbuf 53 * After decompression it will contain the 54 * compressed size, and head.S will read it. 55 */ 56 57static unsigned outcnt = 0; /* bytes in output buffer */ 58 59/* gzip flag byte */ 60#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ 61#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ 62#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 63#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 64#define COMMENT 0x10 /* bit 4 set: file comment present */ 65#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ 66#define RESERVED 0xC0 /* bit 6,7: reserved */ 67 68#define get_byte() inbuf[inptr++] 69 70/* Diagnostic functions */ 71#ifdef DEBUG 72# define Assert(cond,msg) {if(!(cond)) error(msg);} 73# define Trace(x) fprintf x 74# define Tracev(x) {if (verbose) fprintf x ;} 75# define Tracevv(x) {if (verbose>1) fprintf x ;} 76# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} 77# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} 78#else 79# define Assert(cond,msg) 80# define Trace(x) 81# define Tracev(x) 82# define Tracevv(x) 83# define Tracec(c,x) 84# define Tracecv(c,x) 85#endif 86 87static int fill_inbuf(void); 88static void flush_window(void); 89static void error(char *m); 90static void gzip_mark(void **); 91static void gzip_release(void **); 92 93extern char *input_data; /* lives in head.S */ 94 95static long bytes_out = 0; 96static uch *output_data; 97static unsigned long output_ptr = 0; 98 99static void *malloc(int size); 100static void free(void *where); 101static void error(char *m); 102static void gzip_mark(void **); 103static void gzip_release(void **); 104 105static void puts(const char *); 106 107/* the "heap" is put directly after the BSS ends, at end */ 108 109extern int end; 110static long free_mem_ptr = (long)&end; 111 112#include "../../../../lib/inflate.c" 113 114static void *malloc(int size) 115{ 116 void *p; 117 118 if (size <0) error("Malloc error\n"); 119 120 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ 121 122 p = (void *)free_mem_ptr; 123 free_mem_ptr += size; 124 125 return p; 126} 127 128static void free(void *where) 129{ /* Don't care */ 130} 131 132static void gzip_mark(void **ptr) 133{ 134 *ptr = (void *) free_mem_ptr; 135} 136 137static void gzip_release(void **ptr) 138{ 139 free_mem_ptr = (long) *ptr; 140} 141 142/* decompressor info and error messages to serial console */ 143 144static void 145puts(const char *s) 146{ 147#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL 148 while(*s) { 149#ifdef CONFIG_ETRAX_DEBUG_PORT0 150 while(!(*R_SERIAL0_STATUS & (1 << 5))) ; 151 *R_SERIAL0_TR_DATA = *s++; 152#endif 153#ifdef CONFIG_ETRAX_DEBUG_PORT1 154 while(!(*R_SERIAL1_STATUS & (1 << 5))) ; 155 *R_SERIAL1_TR_DATA = *s++; 156#endif 157#ifdef CONFIG_ETRAX_DEBUG_PORT2 158 while(!(*R_SERIAL2_STATUS & (1 << 5))) ; 159 *R_SERIAL2_TR_DATA = *s++; 160#endif 161#ifdef CONFIG_ETRAX_DEBUG_PORT3 162 while(!(*R_SERIAL3_STATUS & (1 << 5))) ; 163 *R_SERIAL3_TR_DATA = *s++; 164#endif 165 } 166#endif 167} 168 169void* 170memset(void* s, int c, size_t n) 171{ 172 int i; 173 char *ss = (char*)s; 174 175 for (i=0;i<n;i++) ss[i] = c; 176} 177 178void* 179memcpy(void* __dest, __const void* __src, 180 size_t __n) 181{ 182 int i; 183 char *d = (char *)__dest, *s = (char *)__src; 184 185 for (i=0;i<__n;i++) d[i] = s[i]; 186} 187 188/* =========================================================================== 189 * Write the output window window[0..outcnt-1] and update crc and bytes_out. 190 * (Used for the decompressed data only.) 191 */ 192 193static void 194flush_window() 195{ 196 ulg c = crc; /* temporary variable */ 197 unsigned n; 198 uch *in, *out, ch; 199 200 in = window; 201 out = &output_data[output_ptr]; 202 for (n = 0; n < outcnt; n++) { 203 ch = *out++ = *in++; 204 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); 205 } 206 crc = c; 207 bytes_out += (ulg)outcnt; 208 output_ptr += (ulg)outcnt; 209 outcnt = 0; 210} 211 212static void 213error(char *x) 214{ 215 puts("\n\n"); 216 puts(x); 217 puts("\n\n -- System halted\n"); 218 219 while(1); /* Halt */ 220} 221 222void 223setup_normal_output_buffer() 224{ 225 output_data = (char *)KERNEL_LOAD_ADR; 226} 227 228void 229decompress_kernel() 230{ 231 char revision; 232 233 /* input_data is set in head.S */ 234 inbuf = input_data; 235 236#ifdef CONFIG_ETRAX_DEBUG_PORT0 237 *R_SERIAL0_XOFF = 0; 238 *R_SERIAL0_BAUD = 0x99; 239 *R_SERIAL0_TR_CTRL = 0x40; 240#endif 241#ifdef CONFIG_ETRAX_DEBUG_PORT1 242 *R_SERIAL1_XOFF = 0; 243 *R_SERIAL1_BAUD = 0x99; 244 *R_SERIAL1_TR_CTRL = 0x40; 245#endif 246#ifdef CONFIG_ETRAX_DEBUG_PORT2 247 *R_GEN_CONFIG = 0x08; 248 *R_SERIAL2_XOFF = 0; 249 *R_SERIAL2_BAUD = 0x99; 250 *R_SERIAL2_TR_CTRL = 0x40; 251#endif 252#ifdef CONFIG_ETRAX_DEBUG_PORT3 253 *R_GEN_CONFIG = 0x100; 254 *R_SERIAL3_XOFF = 0; 255 *R_SERIAL3_BAUD = 0x99; 256 *R_SERIAL3_TR_CTRL = 0x40; 257#endif 258 259 setup_normal_output_buffer(); 260 261 makecrc(); 262 263 __asm__ volatile ("move vr,%0" : "=rm" (revision)); 264 if (revision < 10) 265 { 266 puts("You need an ETRAX 100LX to run linux 2.4\n"); 267 while(1); 268 } 269 270 puts("Uncompressing Linux...\n"); 271 gunzip(); 272 puts("Done. Now booting the kernel.\n"); 273} 274