while others dislike them being extra commits, let's clean them up once and for all for the existing code. If it's ugly, let it only be ugly once :-) Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5507 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
		
			
				
	
	
		
			171 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <string.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
/*
 | 
						|
 * gzip support routine declartions..
 | 
						|
 * =========================================================
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef DEBUG
 | 
						|
#  define Trace(x)
 | 
						|
#  define Tracev(x)
 | 
						|
#  define Tracevv(x)
 | 
						|
#  define Tracec(c,x)
 | 
						|
#  define Tracecv(c,x)
 | 
						|
#  define DBG(x) printf x
 | 
						|
#else
 | 
						|
#  define Trace(x)
 | 
						|
#  define Tracev(x)
 | 
						|
#  define Tracevv(x)
 | 
						|
#  define Tracec(c,x)
 | 
						|
#  define Tracecv(c,x)
 | 
						|
#  define DBG(x)
 | 
						|
#endif
 | 
						|
 | 
						|
void error(char *str)
 | 
						|
{
 | 
						|
	DBG(("%s\n", str));
 | 
						|
}
 | 
						|
 | 
						|
static unsigned char *inbuf;	/* input buffer */
 | 
						|
static unsigned int insize;	/* valid bytes in inbuf */
 | 
						|
static unsigned int inptr;	/* index of next byte to be processed in inbuf */
 | 
						|
 | 
						|
#if !defined(DEBUG)
 | 
						|
#define get_byte()  (inptr < insize ? inbuf[inptr++] : 0)
 | 
						|
#else
 | 
						|
static unsigned char get_byte(void)
 | 
						|
{
 | 
						|
	static int count;
 | 
						|
	unsigned char byte = (inptr < insize ? inbuf[inptr++] : 0);
 | 
						|
#if 0
 | 
						|
	printf("%02x ", byte);
 | 
						|
	if ((++count & 0x0f) == 0) {
 | 
						|
		printf("\n");
 | 
						|
	}
 | 
						|
#endif
 | 
						|
	return byte;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
static void flush_window(void);
 | 
						|
 | 
						|
static long bytes_out;		/* total bytes compressed */
 | 
						|
static unsigned outcnt;		/* bytes in output buffer */
 | 
						|
 | 
						|
#define WSIZE 0x8000		/* Window size must be at least 32k, and a power of two */
 | 
						|
static unsigned char window[WSIZE];	/* Sliding window buffer */
 | 
						|
 | 
						|
/*
 | 
						|
 * gzip declarations
 | 
						|
 */
 | 
						|
 | 
						|
#define OF(args)  args
 | 
						|
#define STATIC static
 | 
						|
 | 
						|
 | 
						|
#define memzero(s, n)     memset ((s), 0, (n))
 | 
						|
 | 
						|
typedef unsigned char uch;
 | 
						|
typedef unsigned short ush;
 | 
						|
typedef unsigned long ulg;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#include "inflate.c"
 | 
						|
 | 
						|
 | 
						|
/* Variables that gunzip doesn't need to see... */
 | 
						|
static unsigned char *output_ptr;
 | 
						|
static unsigned long end_offset;
 | 
						|
static struct unzip_region {
 | 
						|
	unsigned long start;
 | 
						|
	unsigned long end_offset;
 | 
						|
} unzip_region;
 | 
						|
 | 
						|
/* Data provided by the header */
 | 
						|
extern unsigned char zipped_data[];
 | 
						|
extern unsigned char zipped_data_end[];
 | 
						|
extern unsigned char entry;
 | 
						|
/* Assembly language routines */
 | 
						|
extern void jmp_to_program_entry(void *);
 | 
						|
 | 
						|
/* ===========================================================================
 | 
						|
 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 | 
						|
 * (Used for the decompressed data only.)
 | 
						|
 */
 | 
						|
static void flush_window(void)
 | 
						|
{
 | 
						|
	ulg c = crc;		/* temporary variable */
 | 
						|
	unsigned n;
 | 
						|
	unsigned long limit;
 | 
						|
	uch *in, *out, ch;
 | 
						|
 | 
						|
	limit = outcnt;
 | 
						|
 | 
						|
 | 
						|
	n = 0;
 | 
						|
	in = window;
 | 
						|
	while (n < outcnt) {
 | 
						|
		limit = end_offset - bytes_out +n;
 | 
						|
		if (limit > outcnt) {
 | 
						|
			limit = outcnt;
 | 
						|
		}
 | 
						|
		out = output_ptr;
 | 
						|
		DBG(("flush 0x%08lx start 0x%08lx limit 0x%08lx\n",
 | 
						|
			(unsigned long) out, (unsigned long)n, limit));
 | 
						|
		for (; n < limit; n++) {
 | 
						|
			ch = *out++ = *in++;
 | 
						|
			c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
 | 
						|
		}
 | 
						|
		crc = c;
 | 
						|
		bytes_out += (out - output_ptr);
 | 
						|
		output_ptr = out;
 | 
						|
		if (bytes_out == end_offset) {
 | 
						|
			if (output_ptr == (unsigned char *)(&unzip_region+1)) {
 | 
						|
				output_ptr = (unsigned char *)(unzip_region.start);
 | 
						|
				end_offset = unzip_region.end_offset;
 | 
						|
			} else {
 | 
						|
				output_ptr = (unsigned char *)&unzip_region;
 | 
						|
				end_offset += sizeof(unzip_region);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	outcnt = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void gunzip_setup(void)
 | 
						|
{
 | 
						|
	DBG(("gunzip_setup\n"));
 | 
						|
	outcnt = 0;
 | 
						|
	bytes_out = 0;
 | 
						|
 | 
						|
	end_offset = sizeof(unzip_region);
 | 
						|
	output_ptr = (unsigned char *)&unzip_region;
 | 
						|
 | 
						|
	inbuf = &zipped_data[0];
 | 
						|
	insize = zipped_data_end - zipped_data;
 | 
						|
	inptr = 0;
 | 
						|
 | 
						|
	makecrc();
 | 
						|
	DBG(("gunzip_setup_done\n"));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int kunzip(int argc, char **argv)
 | 
						|
{
 | 
						|
	DBG(("kunzip\n"));
 | 
						|
	gunzip_setup();
 | 
						|
	DBG(("pre_gunzip\n"));
 | 
						|
	if (gunzip() != 0) {
 | 
						|
		error("gunzip failed");
 | 
						|
		while(1) {}
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
	DBG(("pre_jmp_to_program_entry: %p\n", &entry ));
 | 
						|
	jmp_to_program_entry(&entry);
 | 
						|
	return 0;
 | 
						|
}
 |