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