diff options
Diffstat (limited to 'recipes/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch')
-rw-r--r-- | recipes/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch | 5308 |
1 files changed, 5308 insertions, 0 deletions
diff --git a/recipes/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch b/recipes/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch new file mode 100644 index 0000000000..48495b5e5f --- /dev/null +++ b/recipes/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch @@ -0,0 +1,5308 @@ +diff -Naru linux/arch/mips/Makefile linux.spi/arch/mips/Makefile +--- linux/arch/mips/Makefile 2004-05-06 15:23:41.000000000 -0400 ++++ linux.spi/arch/mips/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -29,6 +29,8 @@ + endif + + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot ++MAKEZBOOT = $(MAKE) -C arch/$(ARCH)/zboot ++BOOT_TARGETS = zImage zImage.initrd zImage.flash + + check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + +@@ -757,12 +749,16 @@ + + vmlinux.ecoff: vmlinux + @$(MAKEBOOT) $@ ++ ++$(BOOT_TARGETS): vmlinux ++ @$(MAKEZBOOT) $@ + + vmlinux.srec: vmlinux + @$(MAKEBOOT) $@ + + archclean: + @$(MAKEBOOT) clean ++ @$(MAKEZBOOT) clean + rm -f arch/$(ARCH)/ld.script + $(MAKE) -C arch/$(ARCH)/tools clean + $(MAKE) -C arch/mips/baget clean +diff -Naru linux/arch/mips/zboot/common/au1k_uart.c linux.spi/arch/mips/zboot/common/au1k_uart.c +--- linux/arch/mips/zboot/common/au1k_uart.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/au1k_uart.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,103 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * Simple Au1000 uart routines. ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * Author: MontaVista Software, Inc. ++ * ppopov@mvista.com or source@mvista.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include <linux/config.h> ++#include <asm/io.h> ++#include <asm/au1000.h> ++#include "ns16550.h" ++ ++typedef unsigned char uint8; ++typedef unsigned int uint32; ++ ++#define UART16550_BAUD_2400 2400 ++#define UART16550_BAUD_4800 4800 ++#define UART16550_BAUD_9600 9600 ++#define UART16550_BAUD_19200 19200 ++#define UART16550_BAUD_38400 38400 ++#define UART16550_BAUD_57600 57600 ++#define UART16550_BAUD_115200 115200 ++ ++#define UART16550_PARITY_NONE 0 ++#define UART16550_PARITY_ODD 0x08 ++#define UART16550_PARITY_EVEN 0x18 ++#define UART16550_PARITY_MARK 0x28 ++#define UART16550_PARITY_SPACE 0x38 ++ ++#define UART16550_DATA_5BIT 0x0 ++#define UART16550_DATA_6BIT 0x1 ++#define UART16550_DATA_7BIT 0x2 ++#define UART16550_DATA_8BIT 0x3 ++ ++#define UART16550_STOP_1BIT 0x0 ++#define UART16550_STOP_2BIT 0x4 ++ ++/* It would be nice if we had a better way to do this. ++ * It could be a variable defined in one of the board specific files. ++ */ ++#undef UART_BASE ++#ifdef CONFIG_COGENT_CSB250 ++#define UART_BASE UART3_ADDR ++#else ++#define UART_BASE UART0_ADDR ++#endif ++ ++/* memory-mapped read/write of the port */ ++#define UART16550_READ(y) (readl(UART_BASE + y) & 0xff) ++#define UART16550_WRITE(y,z) (writel(z&0xff, UART_BASE + y)) ++ ++/* ++ * We use uart 0, which is already initialized by ++ * yamon. ++ */ ++volatile struct NS16550 * ++serial_init(int chan) ++{ ++ volatile struct NS16550 *com_port; ++ com_port = (struct NS16550 *) UART_BASE; ++ return (com_port); ++} ++ ++void ++serial_putc(volatile struct NS16550 *com_port, unsigned char c) ++{ ++ while ((UART16550_READ(UART_LSR)&0x40) == 0); ++ UART16550_WRITE(UART_TX, c); ++} ++ ++unsigned char ++serial_getc(volatile struct NS16550 *com_port) ++{ ++ while((UART16550_READ(UART_LSR) & 0x1) == 0); ++ return UART16550_READ(UART_RX); ++} ++ ++int ++serial_tstc(volatile struct NS16550 *com_port) ++{ ++ return((UART16550_READ(UART_LSR) & LSR_DR) != 0); ++} +diff -Naru linux/arch/mips/zboot/common/ctype.c linux.spi/arch/mips/zboot/common/ctype.c +--- linux/arch/mips/zboot/common/ctype.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/ctype.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,35 @@ ++/* ++ * linux/lib/ctype.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++#include <linux/ctype.h> ++ ++unsigned char _ctype[] = { ++_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ ++_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ ++_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ ++_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ ++_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ ++_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ ++_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ ++_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ ++_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ ++_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ ++_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ ++_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ ++_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ ++_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ ++_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ ++_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ ++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ ++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ ++_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ ++_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ ++_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ ++_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ ++_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ ++_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ ++ ++ +diff -Naru linux/arch/mips/zboot/common/dummy.c linux.spi/arch/mips/zboot/common/dummy.c +--- linux/arch/mips/zboot/common/dummy.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/dummy.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,4 @@ ++int main(void) ++{ ++ return 0; ++} +diff -Naru linux/arch/mips/zboot/common/Makefile linux.spi/arch/mips/zboot/common/Makefile +--- linux/arch/mips/zboot/common/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,27 @@ ++# ++# arch/mips/zboot/common/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Tom Rini January 2001 ++# ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++clean: ++ rm -rf *.o ++ ++OBJCOPY_ARGS = -O elf32-tradlittlemips ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/common/misc-common.c linux.spi/arch/mips/zboot/common/misc-common.c +--- linux/arch/mips/zboot/common/misc-common.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/misc-common.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,437 @@ ++/* ++ * arch/mips/zboot/common/misc-common.c ++ * ++ * Misc. bootloader code (almost) all platforms can use ++ * ++ * Author: Johnnie Peters <jpeters@mvista.com> ++ * Editor: Tom Rini <trini@mvista.com> ++ * ++ * Derived from arch/ppc/boot/prep/misc.c ++ * ++ * Ported by Pete Popov <ppopov@mvista.com> to ++ * support mips board(s). I also got rid of the vga console ++ * code. ++ * ++ * Copyright 2000-2001 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include <linux/config.h> ++#include "zlib.h" ++#include <stdarg.h> ++ ++extern char *avail_ram; ++extern char *end_avail; ++extern char _end[]; ++ ++void puts(const char *); ++void putc(const char c); ++void puthex(unsigned long val); ++void _bcopy(char *src, char *dst, int len); ++void gunzip(void *, int, unsigned char *, int *); ++static int _cvt(unsigned long val, char *buf, long radix, char *digits); ++ ++void _vprintk(void(*)(const char), const char *, va_list ap); ++ ++struct NS16550 *com_port; ++ ++int serial_tstc(volatile struct NS16550 *); ++unsigned char serial_getc(volatile struct NS16550 *); ++void serial_putc(volatile struct NS16550 *, unsigned char); ++ ++void pause(void) ++{ ++ puts("pause\n"); ++} ++ ++void exit(void) ++{ ++ puts("exit\n"); ++ while(1); ++} ++ ++int tstc(void) ++{ ++ return (serial_tstc(com_port)); ++} ++ ++int getc(void) ++{ ++ while (1) { ++ if (serial_tstc(com_port)) ++ return (serial_getc(com_port)); ++ } ++} ++ ++void ++putc(const char c) ++{ ++ int x,y; ++ ++ serial_putc(com_port, c); ++ if ( c == '\n' ) ++ serial_putc(com_port, '\r'); ++} ++ ++void puts(const char *s) ++{ ++ char c; ++ while ( ( c = *s++ ) != '\0' ) { ++ serial_putc(com_port, c); ++ if ( c == '\n' ) serial_putc(com_port, '\r'); ++ } ++} ++ ++void error(char *x) ++{ ++ puts("\n\n"); ++ puts(x); ++ puts("\n\n -- System halted"); ++ ++ while(1); /* Halt */ ++} ++ ++void *zalloc(void *x, unsigned items, unsigned size) ++{ ++ void *p = avail_ram; ++ ++ size *= items; ++ size = (size + 7) & -8; ++ avail_ram += size; ++ if (avail_ram > end_avail) { ++ puts("oops... out of memory\n"); ++ pause(); ++ } ++ return p; ++} ++ ++void zfree(void *x, void *addr, unsigned nb) ++{ ++} ++ ++#define HEAD_CRC 2 ++#define EXTRA_FIELD 4 ++#define ORIG_NAME 8 ++#define COMMENT 0x10 ++#define RESERVED 0xe0 ++ ++#define DEFLATED 8 ++ ++void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) ++{ ++ z_stream s; ++ int r, i, flags; ++ ++ /* skip header */ ++ i = 10; ++ flags = src[3]; ++ if (src[2] != DEFLATED || (flags & RESERVED) != 0) { ++ puts("bad gzipped data\n"); ++ exit(); ++ } ++ if ((flags & EXTRA_FIELD) != 0) ++ i = 12 + src[10] + (src[11] << 8); ++ if ((flags & ORIG_NAME) != 0) ++ while (src[i++] != 0) ++ ; ++ if ((flags & COMMENT) != 0) ++ while (src[i++] != 0) ++ ; ++ if ((flags & HEAD_CRC) != 0) ++ i += 2; ++ if (i >= *lenp) { ++ puts("gunzip: ran out of data in header\n"); ++ exit(); ++ } ++ ++ s.zalloc = zalloc; ++ s.zfree = zfree; ++ r = inflateInit2(&s, -MAX_WBITS); ++ if (r != Z_OK) { ++ puts("inflateInit2 returned %d\n"); ++ exit(); ++ } ++ s.next_in = src + i; ++ s.avail_in = *lenp - i; ++ s.next_out = dst; ++ s.avail_out = dstlen; ++ r = inflate(&s, Z_FINISH); ++ if (r != Z_OK && r != Z_STREAM_END) { ++ puts("inflate returned %d\n"); ++ exit(); ++ } ++ *lenp = s.next_out - (unsigned char *) dst; ++ inflateEnd(&s); ++} ++ ++void ++puthex(unsigned long val) ++{ ++ ++ unsigned char buf[10]; ++ int i; ++ for (i = 7; i >= 0; i--) ++ { ++ buf[i] = "0123456789ABCDEF"[val & 0x0F]; ++ val >>= 4; ++ } ++ buf[8] = '\0'; ++ puts(buf); ++} ++ ++#define FALSE 0 ++#define TRUE 1 ++ ++void ++_printk(char const *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ _vprintk(putc, fmt, ap); ++ va_end(ap); ++ return; ++} ++ ++#define is_digit(c) ((c >= '0') && (c <= '9')) ++ ++void ++_vprintk(void(*putc)(const char), const char *fmt0, va_list ap) ++{ ++ char c, sign, *cp = 0; ++ int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right; ++ char buf[32]; ++ long val; ++ while ((c = *fmt0++)) ++ { ++ if (c == '%') ++ { ++ c = *fmt0++; ++ left_prec = right_prec = pad_on_right = 0; ++ if (c == '-') ++ { ++ c = *fmt0++; ++ pad_on_right++; ++ } ++ if (c == '0') ++ { ++ zero_fill = TRUE; ++ c = *fmt0++; ++ } else ++ { ++ zero_fill = FALSE; ++ } ++ while (is_digit(c)) ++ { ++ left_prec = (left_prec * 10) + (c - '0'); ++ c = *fmt0++; ++ } ++ if (c == '.') ++ { ++ c = *fmt0++; ++ zero_fill++; ++ while (is_digit(c)) ++ { ++ right_prec = (right_prec * 10) + (c - '0'); ++ c = *fmt0++; ++ } ++ } else ++ { ++ right_prec = left_prec; ++ } ++ sign = '\0'; ++ switch (c) ++ { ++ case 'd': ++ case 'x': ++ case 'X': ++ val = va_arg(ap, long); ++ switch (c) ++ { ++ case 'd': ++ if (val < 0) ++ { ++ sign = '-'; ++ val = -val; ++ } ++ length = _cvt(val, buf, 10, "0123456789"); ++ break; ++ case 'x': ++ length = _cvt(val, buf, 16, "0123456789abcdef"); ++ break; ++ case 'X': ++ length = _cvt(val, buf, 16, "0123456789ABCDEF"); ++ break; ++ } ++ cp = buf; ++ break; ++ case 's': ++ cp = va_arg(ap, char *); ++ length = strlen(cp); ++ break; ++ case 'c': ++ c = va_arg(ap, long /*char*/); ++ (*putc)(c); ++ continue; ++ default: ++ (*putc)('?'); ++ } ++ pad = left_prec - length; ++ if (sign != '\0') ++ { ++ pad--; ++ } ++ if (zero_fill) ++ { ++ c = '0'; ++ if (sign != '\0') ++ { ++ (*putc)(sign); ++ sign = '\0'; ++ } ++ } else ++ { ++ c = ' '; ++ } ++ if (!pad_on_right) ++ { ++ while (pad-- > 0) ++ { ++ (*putc)(c); ++ } ++ } ++ if (sign != '\0') ++ { ++ (*putc)(sign); ++ } ++ while (length-- > 0) ++ { ++ (*putc)(c = *cp++); ++ if (c == '\n') ++ { ++ (*putc)('\r'); ++ } ++ } ++ if (pad_on_right) ++ { ++ while (pad-- > 0) ++ { ++ (*putc)(c); ++ } ++ } ++ } else ++ { ++ (*putc)(c); ++ if (c == '\n') ++ { ++ (*putc)('\r'); ++ } ++ } ++ } ++} ++ ++int ++_cvt(unsigned long val, char *buf, long radix, char *digits) ++{ ++ char temp[80]; ++ char *cp = temp; ++ int length = 0; ++ if (val == 0) ++ { /* Special case */ ++ *cp++ = '0'; ++ } else ++ while (val) ++ { ++ *cp++ = digits[val % radix]; ++ val /= radix; ++ } ++ while (cp != temp) ++ { ++ *buf++ = *--cp; ++ length++; ++ } ++ *buf = '\0'; ++ return (length); ++} ++ ++void ++_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) ++{ ++ int i, c; ++ if ((unsigned int)s > (unsigned int)p) ++ { ++ s = (unsigned int)s - (unsigned int)p; ++ } ++ while (s > 0) ++ { ++ if (base) ++ { ++ _printk("%06X: ", (int)p - (int)base); ++ } else ++ { ++ _printk("%06X: ", p); ++ } ++ for (i = 0; i < 16; i++) ++ { ++ if (i < s) ++ { ++ _printk("%02X", p[i] & 0xFF); ++ } else ++ { ++ _printk(" "); ++ } ++ if ((i % 2) == 1) _printk(" "); ++ if ((i % 8) == 7) _printk(" "); ++ } ++ _printk(" |"); ++ for (i = 0; i < 16; i++) ++ { ++ if (i < s) ++ { ++ c = p[i] & 0xFF; ++ if ((c < 0x20) || (c >= 0x7F)) c = '.'; ++ } else ++ { ++ c = ' '; ++ } ++ _printk("%c", c); ++ } ++ _printk("|\n"); ++ s -= 16; ++ p += 16; ++ } ++} ++ ++void ++_dump_buf(unsigned char *p, int s) ++{ ++ _printk("\n"); ++ _dump_buf_with_offset(p, s, 0); ++} ++ ++/* ++ * Local variables: ++ * c-indent-level: 8 ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * End: ++ */ +diff -Naru linux/arch/mips/zboot/common/misc-simple.c linux.spi/arch/mips/zboot/common/misc-simple.c +--- linux/arch/mips/zboot/common/misc-simple.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/misc-simple.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,127 @@ ++/* ++ * arch/mips/zboot/common/misc-simple.c ++ * ++ * Misc. bootloader code for many machines. This assumes you have are using ++ * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory ++ * below 8MB is free. Finally, it assumes you have a NS16550-style uart for ++ * your serial console. If a machine meets these requirements, it can quite ++ * likely use this code during boot. ++ * ++ * Author: Matt Porter <mporter@mvista.com> ++ * Derived from arch/ppc/boot/prep/misc.c ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include <linux/types.h> ++#include <linux/elf.h> ++#include <linux/config.h> ++ ++#include <asm/page.h> ++#include <asm/processor.h> ++#include <asm/mmu.h> ++ ++#include "zlib.h" ++ ++extern struct NS16550 *com_port; ++ ++char *avail_ram; ++char *end_avail; ++extern char _end[]; ++char *zimage_start; ++ ++#ifdef CONFIG_CMDLINE ++#define CMDLINE CONFIG_CMDLINE ++#else ++#define CMDLINE "" ++#endif ++char cmd_preset[] = CMDLINE; ++char cmd_buf[256]; ++char *cmd_line = cmd_buf; ++ ++/* The linker tells us where the image is. ++*/ ++extern unsigned char __image_begin, __image_end; ++extern unsigned char __ramdisk_begin, __ramdisk_end; ++unsigned long initrd_size; ++ ++extern void puts(const char *); ++extern void putc(const char c); ++extern void puthex(unsigned long val); ++extern void *memcpy(void * __dest, __const void * __src, ++ __kernel_size_t __n); ++extern void gunzip(void *, int, unsigned char *, int *); ++extern void udelay(long delay); ++extern int tstc(void); ++extern int getc(void); ++extern volatile struct NS16550 *serial_init(int chan); ++ ++void ++decompress_kernel(unsigned long load_addr, int num_words, ++ unsigned long cksum, unsigned long *sp) ++{ ++ int timer = 0; ++ extern unsigned long start; ++ char *cp, ch; ++ int i; ++ int zimage_size; ++ ++ com_port = (struct NS16550 *)serial_init(0); ++ ++ initrd_size = (unsigned long)(&__ramdisk_end) - ++ (unsigned long)(&__ramdisk_begin); ++ ++ /* ++ * Reveal where we were loaded at and where we ++ * were relocated to. ++ */ ++ puts("loaded at: "); puthex(load_addr); ++ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); ++ if ( (unsigned long)load_addr != (unsigned long)&start ) ++ { ++ puts("relocated to: "); puthex((unsigned long)&start); ++ puts(" "); ++ puthex((unsigned long)((unsigned long)&start + (4*num_words))); ++ puts("\n"); ++ } ++ ++ /* ++ * We link ourself to an arbitrary low address. When we run, we ++ * relocate outself to that address. __image_being points to ++ * the part of the image where the zImage is. -- Tom ++ */ ++ zimage_start = (char *)(unsigned long)(&__image_begin); ++ zimage_size = (unsigned long)(&__image_end) - ++ (unsigned long)(&__image_begin); ++ ++ /* ++ * The zImage and initrd will be between start and _end, so they've ++ * already been moved once. We're good to go now. -- Tom ++ */ ++ puts("zimage at: "); puthex((unsigned long)zimage_start); ++ puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); ++ puts("\n"); ++ ++ if ( initrd_size ) { ++ puts("initrd at: "); ++ puthex((unsigned long)(&__ramdisk_begin)); ++ puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); ++ } ++ ++ /* assume the chunk below 8M is free */ ++ avail_ram = (char *)AVAIL_RAM_START; ++ end_avail = (char *)AVAIL_RAM_END; ++ ++ /* Display standard Linux/MIPS boot prompt for kernel args */ ++ puts("Uncompressing Linux at load address "); ++ puthex(LOADADDR); ++ puts("\n"); ++ /* I don't like this hard coded gunzip size (fixme) */ ++ gunzip((void *)LOADADDR, 0x400000, zimage_start, &zimage_size); ++ puts("Now booting the kernel\n"); ++} +diff -Naru linux/arch/mips/zboot/common/no_initrd.c linux.spi/arch/mips/zboot/common/no_initrd.c +--- linux/arch/mips/zboot/common/no_initrd.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/no_initrd.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,2 @@ ++char initrd_data[1]; ++int initrd_len = 0; +diff -Naru linux/arch/mips/zboot/common/ns16550.c linux.spi/arch/mips/zboot/common/ns16550.c +--- linux/arch/mips/zboot/common/ns16550.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/ns16550.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,57 @@ ++/* ++ * NS16550 support ++ */ ++ ++#include <linux/config.h> ++#include <asm/serial.h> ++#include "ns16550.h" ++ ++typedef struct NS16550 *NS16550_t; ++ ++const NS16550_t COM_PORTS[] = { (NS16550_t) COM1, ++ (NS16550_t) COM2, ++ (NS16550_t) COM3, ++ (NS16550_t) COM4 }; ++ ++volatile struct NS16550 * ++serial_init(int chan) ++{ ++ volatile struct NS16550 *com_port; ++ com_port = (struct NS16550 *) COM_PORTS[chan]; ++ /* See if port is present */ ++ com_port->lcr = 0x00; ++ com_port->ier = 0xFF; ++#if 0 ++ if (com_port->ier != 0x0F) return ((struct NS16550 *)0); ++#endif ++ com_port->ier = 0x00; ++ com_port->lcr = 0x80; /* Access baud rate */ ++#ifdef CONFIG_SERIAL_CONSOLE_NONSTD ++ com_port->dll = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD); ++ com_port->dlm = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8; ++#endif ++ com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ ++ com_port->mcr = 0x03; /* RTS/DTR */ ++ com_port->fcr = 0x07; /* Clear & enable FIFOs */ ++ return (com_port); ++} ++ ++void ++serial_putc(volatile struct NS16550 *com_port, unsigned char c) ++{ ++ while ((com_port->lsr & LSR_THRE) == 0) ; ++ com_port->thr = c; ++} ++ ++unsigned char ++serial_getc(volatile struct NS16550 *com_port) ++{ ++ while ((com_port->lsr & LSR_DR) == 0) ; ++ return (com_port->rbr); ++} ++ ++int ++serial_tstc(volatile struct NS16550 *com_port) ++{ ++ return ((com_port->lsr & LSR_DR) != 0); ++} +diff -Naru linux/arch/mips/zboot/common/string.c linux.spi/arch/mips/zboot/common/string.c +--- linux/arch/mips/zboot/common/string.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/string.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,497 @@ ++/* ++ * linux/lib/string.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++/* ++ * stupid library routines.. The optimized versions should generally be found ++ * as inline code in <asm-xx/string.h> ++ * ++ * These are buggy as well.. ++ * ++ * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de> ++ * - Added strsep() which will replace strtok() soon (because strsep() is ++ * reentrant and should be faster). Use only strsep() in new code, please. ++ */ ++ ++#include <linux/types.h> ++#include <linux/string.h> ++#include <linux/ctype.h> ++ ++/** ++ * strnicmp - Case insensitive, length-limited string comparison ++ * @s1: One string ++ * @s2: The other string ++ * @len: the maximum number of characters to compare ++ */ ++int strnicmp(const char *s1, const char *s2, size_t len) ++{ ++ /* Yes, Virginia, it had better be unsigned */ ++ unsigned char c1, c2; ++ ++ c1 = 0; c2 = 0; ++ if (len) { ++ do { ++ c1 = *s1; c2 = *s2; ++ s1++; s2++; ++ if (!c1) ++ break; ++ if (!c2) ++ break; ++ if (c1 == c2) ++ continue; ++ c1 = tolower(c1); ++ c2 = tolower(c2); ++ if (c1 != c2) ++ break; ++ } while (--len); ++ } ++ return (int)c1 - (int)c2; ++} ++ ++char * ___strtok; ++ ++#ifndef __HAVE_ARCH_STRCPY ++/** ++ * strcpy - Copy a %NUL terminated string ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ */ ++char * strcpy(char * dest,const char *src) ++{ ++ char *tmp = dest; ++ ++ while ((*dest++ = *src++) != '\0') ++ /* nothing */; ++ return tmp; ++} ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCPY ++/** ++ * strncpy - Copy a length-limited, %NUL-terminated string ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ * @count: The maximum number of bytes to copy ++ * ++ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer. ++ * However, the result is not %NUL-terminated if the source exceeds ++ * @count bytes. ++ */ ++char * strncpy(char * dest,const char *src,size_t count) ++{ ++ char *tmp = dest; ++ ++ while (count-- && (*dest++ = *src++) != '\0') ++ /* nothing */; ++ ++ return tmp; ++} ++#endif ++ ++/** ++ * strcat - Append one %NUL-terminated string to another ++ * @dest: The string to be appended to ++ * @src: The string to append to it ++ */ ++char * strcat(char * dest, const char * src) ++{ ++ char *tmp = dest; ++ ++ while (*dest) ++ dest++; ++ while ((*dest++ = *src++) != '\0') ++ ; ++ ++ return tmp; ++} ++ ++/** ++ * strncat - Append a length-limited, %NUL-terminated string to another ++ * @dest: The string to be appended to ++ * @src: The string to append to it ++ * @count: The maximum numbers of bytes to copy ++ * ++ * Note that in contrast to strncpy, strncat ensures the result is ++ * terminated. ++ */ ++char * strncat(char *dest, const char *src, size_t count) ++{ ++ char *tmp = dest; ++ ++ if (count) { ++ while (*dest) ++ dest++; ++ while ((*dest++ = *src++)) { ++ if (--count == 0) { ++ *dest = '\0'; ++ break; ++ } ++ } ++ } ++ ++ return tmp; ++} ++ ++#ifndef __HAVE_ARCH_STRCMP ++/** ++ * strcmp - Compare two strings ++ * @cs: One string ++ * @ct: Another string ++ */ ++int strcmp(const char * cs,const char * ct) ++{ ++ register signed char __res; ++ ++ while (1) { ++ if ((__res = *cs - *ct++) != 0 || !*cs++) ++ break; ++ } ++ ++ return __res; ++} ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCMP ++/** ++ * strncmp - Compare two length-limited strings ++ * @cs: One string ++ * @ct: Another string ++ * @count: The maximum number of bytes to compare ++ */ ++int strncmp(const char * cs,const char * ct,size_t count) ++{ ++ register signed char __res = 0; ++ ++ while (count) { ++ if ((__res = *cs - *ct++) != 0 || !*cs++) ++ break; ++ count--; ++ } ++ ++ return __res; ++} ++#endif ++ ++/** ++ * strchr - Find the first occurrence of a character in a string ++ * @s: The string to be searched ++ * @c: The character to search for ++ */ ++char * strchr(const char * s, int c) ++{ ++ for(; *s != (char) c; ++s) ++ if (*s == '\0') ++ return NULL; ++ return (char *) s; ++} ++ ++/** ++ * strrchr - Find the last occurrence of a character in a string ++ * @s: The string to be searched ++ * @c: The character to search for ++ */ ++char * strrchr(const char * s, int c) ++{ ++ const char *p = s + strlen(s); ++ do { ++ if (*p == (char)c) ++ return (char *)p; ++ } while (--p >= s); ++ return NULL; ++} ++ ++/** ++ * strlen - Find the length of a string ++ * @s: The string to be sized ++ */ ++size_t strlen(const char * s) ++{ ++ const char *sc; ++ ++ for (sc = s; *sc != '\0'; ++sc) ++ /* nothing */; ++ return sc - s; ++} ++ ++/** ++ * strnlen - Find the length of a length-limited string ++ * @s: The string to be sized ++ * @count: The maximum number of bytes to search ++ */ ++size_t strnlen(const char * s, size_t count) ++{ ++ const char *sc; ++ ++ for (sc = s; count-- && *sc != '\0'; ++sc) ++ /* nothing */; ++ return sc - s; ++} ++ ++/** ++ * strspn - Calculate the length of the initial substring of @s which only ++ * contain letters in @accept ++ * @s: The string to be searched ++ * @accept: The string to search for ++ */ ++size_t strspn(const char *s, const char *accept) ++{ ++ const char *p; ++ const char *a; ++ size_t count = 0; ++ ++ for (p = s; *p != '\0'; ++p) { ++ for (a = accept; *a != '\0'; ++a) { ++ if (*p == *a) ++ break; ++ } ++ if (*a == '\0') ++ return count; ++ ++count; ++ } ++ ++ return count; ++} ++ ++/** ++ * strpbrk - Find the first occurrence of a set of characters ++ * @cs: The string to be searched ++ * @ct: The characters to search for ++ */ ++char * strpbrk(const char * cs,const char * ct) ++{ ++ const char *sc1,*sc2; ++ ++ for( sc1 = cs; *sc1 != '\0'; ++sc1) { ++ for( sc2 = ct; *sc2 != '\0'; ++sc2) { ++ if (*sc1 == *sc2) ++ return (char *) sc1; ++ } ++ } ++ return NULL; ++} ++ ++/** ++ * strtok - Split a string into tokens ++ * @s: The string to be searched ++ * @ct: The characters to search for ++ * ++ * WARNING: strtok is deprecated, use strsep instead. ++ */ ++char * strtok(char * s,const char * ct) ++{ ++ char *sbegin, *send; ++ ++ sbegin = s ? s : ___strtok; ++ if (!sbegin) { ++ return NULL; ++ } ++ sbegin += strspn(sbegin,ct); ++ if (*sbegin == '\0') { ++ ___strtok = NULL; ++ return( NULL ); ++ } ++ send = strpbrk( sbegin, ct); ++ if (send && *send != '\0') ++ *send++ = '\0'; ++ ___strtok = send; ++ return (sbegin); ++} ++ ++/** ++ * strsep - Split a string into tokens ++ * @s: The string to be searched ++ * @ct: The characters to search for ++ * ++ * strsep() updates @s to point after the token, ready for the next call. ++ * ++ * It returns empty tokens, too, behaving exactly like the libc function ++ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. ++ * Same semantics, slimmer shape. ;) ++ */ ++char * strsep(char **s, const char *ct) ++{ ++ char *sbegin = *s, *end; ++ ++ if (sbegin == NULL) ++ return NULL; ++ ++ end = strpbrk(sbegin, ct); ++ if (end) ++ *end++ = '\0'; ++ *s = end; ++ ++ return sbegin; ++} ++ ++/** ++ * memset - Fill a region of memory with the given value ++ * @s: Pointer to the start of the area. ++ * @c: The byte to fill the area with ++ * @count: The size of the area. ++ * ++ * Do not use memset() to access IO space, use memset_io() instead. ++ */ ++void * memset(void * s,int c, size_t count) ++{ ++ char *xs = (char *) s; ++ ++ while (count--) ++ *xs++ = c; ++ ++ return s; ++} ++ ++/** ++ * bcopy - Copy one area of memory to another ++ * @src: Where to copy from ++ * @dest: Where to copy to ++ * @count: The size of the area. ++ * ++ * Note that this is the same as memcpy(), with the arguments reversed. ++ * memcpy() is the standard, bcopy() is a legacy BSD function. ++ * ++ * You should not use this function to access IO space, use memcpy_toio() ++ * or memcpy_fromio() instead. ++ */ ++char * bcopy(const char * src, char * dest, int count) ++{ ++ char *tmp = dest; ++ ++ while (count--) ++ *tmp++ = *src++; ++ ++ return dest; ++} ++ ++/** ++ * memcpy - Copy one area of memory to another ++ * @dest: Where to copy to ++ * @src: Where to copy from ++ * @count: The size of the area. ++ * ++ * You should not use this function to access IO space, use memcpy_toio() ++ * or memcpy_fromio() instead. ++ */ ++void * memcpy(void * dest,const void *src,size_t count) ++{ ++ char *tmp = (char *) dest, *s = (char *) src; ++ ++ while (count--) ++ *tmp++ = *s++; ++ ++ return dest; ++} ++ ++/** ++ * memmove - Copy one area of memory to another ++ * @dest: Where to copy to ++ * @src: Where to copy from ++ * @count: The size of the area. ++ * ++ * Unlike memcpy(), memmove() copes with overlapping areas. ++ */ ++void * memmove(void * dest,const void *src,size_t count) ++{ ++ char *tmp, *s; ++ ++ if (dest <= src) { ++ tmp = (char *) dest; ++ s = (char *) src; ++ while (count--) ++ *tmp++ = *s++; ++ } ++ else { ++ tmp = (char *) dest + count; ++ s = (char *) src + count; ++ while (count--) ++ *--tmp = *--s; ++ } ++ ++ return dest; ++} ++ ++/** ++ * memcmp - Compare two areas of memory ++ * @cs: One area of memory ++ * @ct: Another area of memory ++ * @count: The size of the area. ++ */ ++int memcmp(const void * cs,const void * ct,size_t count) ++{ ++ const unsigned char *su1, *su2; ++ signed char res = 0; ++ ++ for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) ++ if ((res = *su1 - *su2) != 0) ++ break; ++ return res; ++} ++ ++#ifndef __HAVE_ARCH_MEMSCAN ++/** ++ * memscan - Find a character in an area of memory. ++ * @addr: The memory area ++ * @c: The byte to search for ++ * @size: The size of the area. ++ * ++ * returns the address of the first occurrence of @c, or 1 byte past ++ * the area if @c is not found ++ */ ++void * memscan(void * addr, int c, size_t size) ++{ ++ unsigned char * p = (unsigned char *) addr; ++ unsigned char * e = p + size; ++ ++ while (p != e) { ++ if (*p == c) ++ return (void *) p; ++ p++; ++ } ++ ++ return (void *) p; ++} ++#endif ++ ++/** ++ * strstr - Find the first substring in a %NUL terminated string ++ * @s1: The string to be searched ++ * @s2: The string to search for ++ */ ++char * strstr(const char * s1,const char * s2) ++{ ++ int l1, l2; ++ ++ l2 = strlen(s2); ++ if (!l2) ++ return (char *) s1; ++ l1 = strlen(s1); ++ while (l1 >= l2) { ++ l1--; ++ if (!memcmp(s1,s2,l2)) ++ return (char *) s1; ++ s1++; ++ } ++ return NULL; ++} ++ ++/** ++ * memchr - Find a character in an area of memory. ++ * @s: The memory area ++ * @c: The byte to search for ++ * @n: The size of the area. ++ * ++ * returns the address of the first occurrence of @c, or %NULL ++ * if @c is not found ++ */ ++void *memchr(const void *s, int c, size_t n) ++{ ++ const unsigned char *p = s; ++ while (n-- != 0) { ++ if ((unsigned char)c == *p++) { ++ return (void *)(p-1); ++ } ++ } ++ return NULL; ++} +diff -Naru linux/arch/mips/zboot/csb250/head.S linux.spi/arch/mips/zboot/csb250/head.S +--- linux/arch/mips/zboot/csb250/head.S 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/csb250/head.S 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,157 @@ ++/* ++ * arch/mips/kernel/head.S ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1994, 1995 Waldorf Electronics ++ * Written by Ralf Baechle and Andreas Busse ++ * Copyright (C) 1995 - 1999 Ralf Baechle ++ * Copyright (C) 1996 Paul M. Antoine ++ * Modified for DECStation and hence R3000 support by Paul M. Antoine ++ * Further modifications by David S. Miller and Harald Koerfgen ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * ++ * Head.S contains the MIPS exception handler and startup code. ++ * ++ ************************************************************************** ++ * 9 Nov, 2000. ++ * Added Cache Error exception handler and SBDDP EJTAG debug exception. ++ * ++ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ ************************************************************************** ++ */ ++#include <linux/config.h> ++#include <linux/threads.h> ++ ++#include <asm/asm.h> ++#include <asm/cacheops.h> ++#include <asm/mipsregs.h> ++#include <asm/offset.h> ++#include <asm/cachectl.h> ++#include <asm/regdef.h> ++ ++#define IndexInvalidate_I 0x00 ++#define IndexWriteBack_D 0x01 ++ ++ .set noreorder ++ .cprestore ++ LEAF(start) ++start: ++ bal locate ++ nop ++ ++ .globl asize /* Someday we'll put the initrd info here. */ ++asize: .word 0 ++ .word 0 ++ .word 0 ++ .word 0 ++ ++locate: ++ subu s8, ra, 8 /* Where we were loaded */ ++ la sp, (.stack + 8192) ++ ++ move s0, a0 /* Save boot rom start args */ ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ la a0, start /* Where we were linked to run */ ++ ++ move a1, s8 ++ la a2, _edata ++ subu t1, a2, a0 ++ srl t1, t1, 2 ++ ++ /* copy text section */ ++ li t0, 0 ++1: lw v0, 0(a1) ++ nop ++ sw v0, 0(a0) ++ xor t0, t0, v0 ++ addu a0, 4 ++ bne a2, a0, 1b ++ addu a1, 4 ++ ++ /* Clear BSS */ ++ la a0, _edata ++ la a2, _end ++2: sw zero, 0(a0) ++ bne a2, a0, 2b ++ addu a0, 4 ++ ++ /* push the D-Cache and invalidate I-Cache */ ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ /* done */ ++ ++/* move a0, s8 /* load address */ ++ subu a0, s8, 0x1000 /* load address */ ++ move a1, t1 /* length in words */ ++ move a2, t0 /* checksum */ ++ move a3, sp ++ ++ la ra, 1f ++ la k0, decompress_kernel ++ jr k0 ++ nop ++1: ++ ++ la a2, __ramdisk_begin ++ la a3, initrd_size ++ lw a0, 0(a2) ++ lw a1, 0(a3) ++ li k0, KERNEL_ENTRY ++ jr k0 ++ nop ++3: ++ b 3b ++ END(start) ++ ++ LEAF(udelay) ++udelay: ++ END(udelay) ++ ++ ++ LEAF(FlushCache) ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ jr ra ++ nop ++ END(FlushCache) ++ ++ .comm .stack,4096*2,4 +diff -Naru linux/arch/mips/zboot/csb250/Makefile linux.spi/arch/mips/zboot/csb250/Makefile +--- linux/arch/mips/zboot/csb250/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/csb250/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,90 @@ ++# arch/mips/zboot/pb1xxx/Makefile ++# ++# Makefile for Cogent CSB250 Au1500 board. ++# All of the boot loader code was derived from the ppc ++# boot code. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++######################################################################### ++# START BOARD SPECIFIC VARIABLES ++BNAME=csb250 ++ ++# These two variables control where the zImage is stored ++# in flash and loaded in memory. It only controls how the srec ++# file is generated, the code is the same. ++RAM_RUN_ADDR = 0x80a00000 ++FLASH_LOAD_ADDR = 0xBFD00000 ++ ++# These two variables specify the free ram region ++# that can be used for temporary malloc area ++AVAIL_RAM_START=0x80400000 ++AVAIL_RAM_END=0x80800000 ++ ++# This one must match the LOADADDR in arch/mips/Makefile! ++LOADADDR=0x80100000 ++# END BOARD SPECIFIC VARIABLES ++######################################################################### ++ ++OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ ++ ../common/au1k_uart.o ../common/string.o ../common/ctype.o ++LIBS := ../lib/zlib.a ++ ++ENTRY := ../utils/entry ++OFFSET := ../utils/offset ++SIZE := ../utils/size ++ ++LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic ++OBJCOPY_ARGS = -O elf32-tradbigmips ++ ++all: zImage ++ ++clean: ++ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec ++ ++head.o: head.S $(TOPDIR)/vmlinux ++ $(CC) $(AFLAGS) \ ++ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \ ++ -c -o $*.o $< ++ ++../common/misc-simple.o: ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -DZIMAGE_SIZE=0 -c -o $@ $*.c ++ ++zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o ++ $(OBJCOPY) \ ++ --add-section=.image=../images/vmlinux.gz \ ++ --set-section-flags=.image=contents,alloc,load,readonly,data \ ++ ../common/dummy.o image.o ++ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \ ++ -R .initrd -R .sysmap ++ ++# Here we manipulate the image in order to get it the necessary ++# srecord file we need. ++zImage: zvmlinux ++ mv zvmlinux ../images/zImage.$(BNAME) ++ $(OBJCOPY) -O binary ../images/zImage.$(BNAME) ../images/$(BNAME).bin ++ ++zImage.flash: zImage ++ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \ ++ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/images/Makefile linux.spi/arch/mips/zboot/images/Makefile +--- linux/arch/mips/zboot/images/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/images/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,10 @@ ++ ++include $(TOPDIR)/Rules.make ++ ++vmlinux.gz: $(TOPDIR)/vmlinux ++ $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux ++ gzip -vf vmlinux ++ ++clean: ++ rm -f vmlinux.* zImage.* ++ +diff -Naru linux/arch/mips/zboot/include/nonstdio.h linux.spi/arch/mips/zboot/include/nonstdio.h +--- linux/arch/mips/zboot/include/nonstdio.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/nonstdio.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (C) Paul Mackerras 1997. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++typedef int FILE; ++extern FILE *stdin, *stdout; ++#define NULL ((void *)0) ++#define EOF (-1) ++#define fopen(n, m) NULL ++#define fflush(f) 0 ++#define fclose(f) 0 ++extern char *fgets(); ++ ++#define perror(s) printf("%s: no files!\n", (s)) +diff -Naru linux/arch/mips/zboot/include/ns16550.h linux.spi/arch/mips/zboot/include/ns16550.h +--- linux/arch/mips/zboot/include/ns16550.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/ns16550.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,49 @@ ++/* ++ * NS16550 Serial Port ++ */ ++ ++/* ++ * Figure out which file will have the definitons of COMx ++ */ ++#if !defined(CONFIG_AU1X00_UART) ++#error no serial.h ++#endif ++ ++/* Some machines have their uart registers 16 bytes apart. Most don't. ++ * TODO: Make this work like drivers/char/serial does - Tom */ ++#if !defined(UART_REG_PAD) ++#define UART_REG_PAD(x) ++#endif ++ ++struct NS16550 ++ { ++ unsigned char rbr; /* 0 */ ++ UART_REG_PAD(rbr) ++ unsigned char ier; /* 1 */ ++ UART_REG_PAD(ier) ++ unsigned char fcr; /* 2 */ ++ UART_REG_PAD(fcr) ++ unsigned char lcr; /* 3 */ ++ UART_REG_PAD(lcr) ++ unsigned char mcr; /* 4 */ ++ UART_REG_PAD(mcr) ++ unsigned char lsr; /* 5 */ ++ UART_REG_PAD(lsr) ++ unsigned char msr; /* 6 */ ++ UART_REG_PAD(msr) ++ unsigned char scr; /* 7 */ ++ }; ++ ++#define thr rbr ++#define iir fcr ++#define dll rbr ++#define dlm ier ++ ++#define LSR_DR 0x01 /* Data ready */ ++#define LSR_OE 0x02 /* Overrun */ ++#define LSR_PE 0x04 /* Parity error */ ++#define LSR_FE 0x08 /* Framing error */ ++#define LSR_BI 0x10 /* Break */ ++#define LSR_THRE 0x20 /* Xmit holding register empty */ ++#define LSR_TEMT 0x40 /* Xmitter empty */ ++#define LSR_ERR 0x80 /* Error */ +diff -Naru linux/arch/mips/zboot/include/pb1000_serial.h linux.spi/arch/mips/zboot/include/pb1000_serial.h +--- linux/arch/mips/zboot/include/pb1000_serial.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/pb1000_serial.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,20 @@ ++/* ++ * arch/ppc/boot/include/sandpoint_serial.h ++ * ++ * Location of the COM ports on Motorola SPS Sandpoint machines ++ * ++ * Author: Mark A. Greer ++ * mgreer@mvista.com ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#define COM1 0xfe0003f8 ++#define COM2 0xfe0002f8 ++#define COM3 0x00000000 /* No COM3 */ ++#define COM4 0x00000000 /* No COM4 */ +diff -Naru linux/arch/mips/zboot/include/zlib.h linux.spi/arch/mips/zboot/include/zlib.h +--- linux/arch/mips/zboot/include/zlib.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/zlib.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,432 @@ ++/* $Id: zlib.h,v 1.2 2002/02/16 16:55:45 ppopov Exp $ */ ++ ++/* ++ * This file is derived from zlib.h and zconf.h from the zlib-0.95 ++ * distribution by Jean-loup Gailly and Mark Adler, with some additions ++ * by Paul Mackerras to aid in implementing Deflate compression and ++ * decompression for PPP packets. ++ */ ++ ++/* ++ * ==FILEVERSION 960122== ++ * ++ * This marker is used by the Linux installation script to determine ++ * whether an up-to-date version of this file is already installed. ++ */ ++ ++/* zlib.h -- interface of the 'zlib' general purpose compression library ++ version 0.95, Aug 16th, 1995. ++ ++ Copyright (C) 1995 Jean-loup Gailly and Mark Adler ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ Jean-loup Gailly Mark Adler ++ gzip@prep.ai.mit.edu madler@alumni.caltech.edu ++ */ ++ ++#ifndef _ZLIB_H ++#define _ZLIB_H ++ ++/* #include "zconf.h" */ /* included directly here */ ++ ++/* zconf.h -- configuration of the zlib compression library ++ * Copyright (C) 1995 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ ++ ++/* ++ The library does not install any signal handler. It is recommended to ++ add at least a handler for SIGSEGV when decompressing; the library checks ++ the consistency of the input data whenever possible but may go nuts ++ for some forms of corrupted input. ++ */ ++ ++/* ++ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more ++ * than 64k bytes at a time (needed on systems with 16-bit int). ++ * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints ++ * at addresses which are not a multiple of their size. ++ * Under DOS, -DFAR=far or -DFAR=__far may be needed. ++ */ ++ ++#ifndef STDC ++# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) ++# define STDC ++# endif ++#endif ++ ++#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ ++# include <unix.h> ++#endif ++ ++/* Maximum value for memLevel in deflateInit2 */ ++#ifndef MAX_MEM_LEVEL ++# ifdef MAXSEG_64K ++# define MAX_MEM_LEVEL 8 ++# else ++# define MAX_MEM_LEVEL 9 ++# endif ++#endif ++ ++#ifndef FAR ++# define FAR ++#endif ++ ++/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ ++#ifndef MAX_WBITS ++# define MAX_WBITS 15 /* 32K LZ77 window */ ++#endif ++ ++/* The memory requirements for deflate are (in bytes): ++ 1 << (windowBits+2) + 1 << (memLevel+9) ++ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) ++ plus a few kilobytes for small objects. For example, if you want to reduce ++ the default memory requirements from 256K to 128K, compile with ++ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" ++ Of course this will generally degrade compression (there's no free lunch). ++ ++ The memory requirements for inflate are (in bytes) 1 << windowBits ++ that is, 32K for windowBits=15 (default value) plus a few kilobytes ++ for small objects. ++*/ ++ ++ /* Type declarations */ ++ ++#ifndef OF /* function prototypes */ ++# ifdef STDC ++# define OF(args) args ++# else ++# define OF(args) () ++# endif ++#endif ++ ++typedef unsigned char Byte; /* 8 bits */ ++typedef unsigned int uInt; /* 16 bits or more */ ++typedef unsigned long uLong; /* 32 bits or more */ ++ ++typedef Byte FAR Bytef; ++typedef char FAR charf; ++typedef int FAR intf; ++typedef uInt FAR uIntf; ++typedef uLong FAR uLongf; ++ ++#ifdef STDC ++ typedef void FAR *voidpf; ++ typedef void *voidp; ++#else ++ typedef Byte FAR *voidpf; ++ typedef Byte *voidp; ++#endif ++ ++/* end of original zconf.h */ ++ ++#define ZLIB_VERSION "0.95P" ++ ++/* ++ The 'zlib' compression library provides in-memory compression and ++ decompression functions, including integrity checks of the uncompressed ++ data. This version of the library supports only one compression method ++ (deflation) but other algorithms may be added later and will have the same ++ stream interface. ++ ++ For compression the application must provide the output buffer and ++ may optionally provide the input buffer for optimization. For decompression, ++ the application must provide the input buffer and may optionally provide ++ the output buffer for optimization. ++ ++ Compression can be done in a single step if the buffers are large ++ enough (for example if an input file is mmap'ed), or can be done by ++ repeated calls of the compression function. In the latter case, the ++ application must provide more input and/or consume the output ++ (providing more output space) before each call. ++*/ ++ ++typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); ++typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); ++ ++struct internal_state; ++ ++typedef struct z_stream_s { ++ Bytef *next_in; /* next input byte */ ++ uInt avail_in; /* number of bytes available at next_in */ ++ uLong total_in; /* total nb of input bytes read so far */ ++ ++ Bytef *next_out; /* next output byte should be put there */ ++ uInt avail_out; /* remaining free space at next_out */ ++ uLong total_out; /* total nb of bytes output so far */ ++ ++ char *msg; /* last error message, NULL if no error */ ++ struct internal_state FAR *state; /* not visible by applications */ ++ ++ alloc_func zalloc; /* used to allocate the internal state */ ++ free_func zfree; /* used to free the internal state */ ++ voidp opaque; /* private data object passed to zalloc and zfree */ ++ ++ Byte data_type; /* best guess about the data type: ascii or binary */ ++ ++} z_stream; ++ ++/* ++ The application must update next_in and avail_in when avail_in has ++ dropped to zero. It must update next_out and avail_out when avail_out ++ has dropped to zero. The application must initialize zalloc, zfree and ++ opaque before calling the init function. All other fields are set by the ++ compression library and must not be updated by the application. ++ ++ The opaque value provided by the application will be passed as the first ++ parameter for calls of zalloc and zfree. This can be useful for custom ++ memory management. The compression library attaches no meaning to the ++ opaque value. ++ ++ zalloc must return Z_NULL if there is not enough memory for the object. ++ On 16-bit systems, the functions zalloc and zfree must be able to allocate ++ exactly 65536 bytes, but will not be required to allocate more than this ++ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, ++ pointers returned by zalloc for objects of exactly 65536 bytes *must* ++ have their offset normalized to zero. The default allocation function ++ provided by this library ensures this (see zutil.c). To reduce memory ++ requirements and avoid any allocation of 64K objects, at the expense of ++ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). ++ ++ The fields total_in and total_out can be used for statistics or ++ progress reports. After compression, total_in holds the total size of ++ the uncompressed data and may be saved for use in the decompressor ++ (particularly if the decompressor wants to decompress everything in ++ a single step). ++*/ ++ ++ /* constants */ ++ ++#define Z_NO_FLUSH 0 ++#define Z_PARTIAL_FLUSH 1 ++#define Z_FULL_FLUSH 2 ++#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ ++#define Z_FINISH 4 ++#define Z_PACKET_FLUSH 5 ++/* See deflate() below for the usage of these constants */ ++ ++#define Z_OK 0 ++#define Z_STREAM_END 1 ++#define Z_ERRNO (-1) ++#define Z_STREAM_ERROR (-2) ++#define Z_DATA_ERROR (-3) ++#define Z_MEM_ERROR (-4) ++#define Z_BUF_ERROR (-5) ++/* error codes for the compression/decompression functions */ ++ ++#define Z_BEST_SPEED 1 ++#define Z_BEST_COMPRESSION 9 ++#define Z_DEFAULT_COMPRESSION (-1) ++/* compression levels */ ++ ++#define Z_FILTERED 1 ++#define Z_HUFFMAN_ONLY 2 ++#define Z_DEFAULT_STRATEGY 0 ++ ++#define Z_BINARY 0 ++#define Z_ASCII 1 ++#define Z_UNKNOWN 2 ++/* Used to set the data_type field */ ++ ++#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ ++ ++extern char *zlib_version; ++/* The application can compare zlib_version and ZLIB_VERSION for consistency. ++ If the first character differs, the library code actually used is ++ not compatible with the zlib.h header file used by the application. ++ */ ++ ++ /* basic functions */ ++ ++extern int inflateInit OF((z_stream *strm)); ++/* ++ Initializes the internal stream state for decompression. The fields ++ zalloc and zfree must be initialized before by the caller. If zalloc and ++ zfree are set to Z_NULL, inflateInit updates them to use default allocation ++ functions. ++ ++ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not ++ enough memory. msg is set to null if there is no error message. ++ inflateInit does not perform any decompression: this will be done by ++ inflate(). ++*/ ++ ++ ++extern int inflate OF((z_stream *strm, int flush)); ++/* ++ Performs one or both of the following actions: ++ ++ - Decompress more input starting at next_in and update next_in and avail_in ++ accordingly. If not all input can be processed (because there is not ++ enough room in the output buffer), next_in is updated and processing ++ will resume at this point for the next call of inflate(). ++ ++ - Provide more output starting at next_out and update next_out and avail_out ++ accordingly. inflate() always provides as much output as possible ++ (until there is no more input data or no more space in the output buffer). ++ ++ Before the call of inflate(), the application should ensure that at least ++ one of the actions is possible, by providing more input and/or consuming ++ more output, and updating the next_* and avail_* values accordingly. ++ The application can consume the uncompressed output when it wants, for ++ example when the output buffer is full (avail_out == 0), or after each ++ call of inflate(). ++ ++ If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, ++ inflate flushes as much output as possible to the output buffer. The ++ flushing behavior of inflate is not specified for values of the flush ++ parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the ++ current implementation actually flushes as much output as possible ++ anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data ++ has been consumed, it is expecting to see the length field of a stored ++ block; if not, it returns Z_DATA_ERROR. ++ ++ inflate() should normally be called until it returns Z_STREAM_END or an ++ error. However if all decompression is to be performed in a single step ++ (a single call of inflate), the parameter flush should be set to ++ Z_FINISH. In this case all pending input is processed and all pending ++ output is flushed; avail_out must be large enough to hold all the ++ uncompressed data. (The size of the uncompressed data may have been saved ++ by the compressor for this purpose.) The next operation on this stream must ++ be inflateEnd to deallocate the decompression state. The use of Z_FINISH ++ is never required, but can be used to inform inflate that a faster routine ++ may be used for the single inflate() call. ++ ++ inflate() returns Z_OK if some progress has been made (more input ++ processed or more output produced), Z_STREAM_END if the end of the ++ compressed data has been reached and all uncompressed output has been ++ produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if ++ the stream structure was inconsistent (for example if next_in or next_out ++ was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no ++ progress is possible or if there was not enough room in the output buffer ++ when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then ++ call inflateSync to look for a good compression block. */ ++ ++ ++extern int inflateEnd OF((z_stream *strm)); ++/* ++ All dynamically allocated data structures for this stream are freed. ++ This function discards any unprocessed input and does not flush any ++ pending output. ++ ++ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state ++ was inconsistent. In the error case, msg may be set but then points to a ++ static string (which must not be deallocated). ++*/ ++ ++ /* advanced functions */ ++ ++extern int inflateInit2 OF((z_stream *strm, ++ int windowBits)); ++/* ++ This is another version of inflateInit with more compression options. The ++ fields next_out, zalloc and zfree must be initialized before by the caller. ++ ++ The windowBits parameter is the base two logarithm of the maximum window ++ size (the size of the history buffer). It should be in the range 8..15 for ++ this version of the library (the value 16 will be allowed soon). The ++ default value is 15 if inflateInit is used instead. If a compressed stream ++ with a larger window size is given as input, inflate() will return with ++ the error code Z_DATA_ERROR instead of trying to allocate a larger window. ++ ++ If next_out is not null, the library will use this buffer for the history ++ buffer; the buffer must either be large enough to hold the entire output ++ data, or have at least 1<<windowBits bytes. If next_out is null, the ++ library will allocate its own buffer (and leave next_out null). next_in ++ need not be provided here but must be provided by the application for the ++ next call of inflate(). ++ ++ If the history buffer is provided by the application, next_out must ++ never be changed by the application since the decompressor maintains ++ history information inside this buffer from call to call; the application ++ can only reset next_out to the beginning of the history buffer when ++ avail_out is zero and all output has been consumed. ++ ++ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was ++ not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as ++ windowBits < 8). msg is set to null if there is no error message. ++ inflateInit2 does not perform any decompression: this will be done by ++ inflate(). ++*/ ++ ++extern int inflateSync OF((z_stream *strm)); ++/* ++ Skips invalid compressed data until the special marker (see deflate() ++ above) can be found, or until all available input is skipped. No output ++ is provided. ++ ++ inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR ++ if no more input was provided, Z_DATA_ERROR if no marker has been found, ++ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success ++ case, the application may save the current current value of total_in which ++ indicates where valid compressed data was found. In the error case, the ++ application may repeatedly call inflateSync, providing more input each time, ++ until success or end of the input data. ++*/ ++ ++extern int inflateReset OF((z_stream *strm)); ++/* ++ This function is equivalent to inflateEnd followed by inflateInit, ++ but does not free and reallocate all the internal decompression state. ++ The stream will keep attributes that may have been set by inflateInit2. ++ ++ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source ++ stream state was inconsistent (such as zalloc or state being NULL). ++*/ ++ ++extern int inflateIncomp OF((z_stream *strm)); ++/* ++ This function adds the data at next_in (avail_in bytes) to the output ++ history without performing any output. There must be no pending output, ++ and the decompressor must be expecting to see the start of a block. ++ Calling this function is equivalent to decompressing a stored block ++ containing the data at next_in (except that the data is not output). ++*/ ++ ++ /* checksum functions */ ++ ++/* ++ This function is not related to compression but is exported ++ anyway because it might be useful in applications using the ++ compression library. ++*/ ++ ++extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); ++ ++/* ++ Update a running Adler-32 checksum with the bytes buf[0..len-1] and ++ return the updated checksum. If buf is NULL, this function returns ++ the required initial value for the checksum. ++ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed ++ much faster. Usage example: ++ ++ uLong adler = adler32(0L, Z_NULL, 0); ++ ++ while (read_buffer(buffer, length) != EOF) { ++ adler = adler32(adler, buffer, length); ++ } ++ if (adler != original_adler) error(); ++*/ ++ ++#ifndef _Z_UTIL_H ++ struct internal_state {int dummy;}; /* hack for buggy compilers */ ++#endif ++ ++#endif /* _ZLIB_H */ +diff -Naru linux/arch/mips/zboot/ld.script linux.spi/arch/mips/zboot/ld.script +--- linux/arch/mips/zboot/ld.script 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/ld.script 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,151 @@ ++OUTPUT_ARCH(mips) ++ENTRY(start) ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ /* . = 0x81000000; */ ++ .init : { *(.init) } =0 ++ .text : ++ { ++ _ftext = . ; ++ *(.text) ++ *(.rodata) ++ *(.rodata1) ++ /* .gnu.warning sections are handled specially by elf32.em. */ ++ *(.gnu.warning) ++ } =0 ++ .kstrtab : { *(.kstrtab) } ++ ++ . = ALIGN(16); /* Exception table */ ++ __start___ex_table = .; ++ __ex_table : { *(__ex_table) } ++ __stop___ex_table = .; ++ ++ __start___dbe_table = .; /* Exception table for data bus errors */ ++ __dbe_table : { *(__dbe_table) } ++ __stop___dbe_table = .; ++ ++ __start___ksymtab = .; /* Kernel symbol table */ ++ __ksymtab : { *(__ksymtab) } ++ __stop___ksymtab = .; ++ ++ _etext = .; ++ ++ . = ALIGN(8192); ++ .data.init_task : { *(.data.init_task) } ++ ++ /* Startup code */ ++ . = ALIGN(4096); ++ __init_begin = .; ++ .text.init : { *(.text.init) } ++ .data.init : { *(.data.init) } ++ . = ALIGN(16); ++ __setup_start = .; ++ .setup.init : { *(.setup.init) } ++ __setup_end = .; ++ __initcall_start = .; ++ .initcall.init : { *(.initcall.init) } ++ __initcall_end = .; ++ . = ALIGN(4096); /* Align double page for init_task_union */ ++ __init_end = .; ++ ++ . = ALIGN(4096); ++ .data.page_aligned : { *(.data.idt) } ++ ++ . = ALIGN(32); ++ .data.cacheline_aligned : { *(.data.cacheline_aligned) } ++ ++ .fini : { *(.fini) } =0 ++ .reginfo : { *(.reginfo) } ++ /* Adjust the address for the data segment. We want to adjust up to ++ the same address within the page on the next page up. It would ++ be more correct to do this: ++ . = .; ++ The current expression does not correctly handle the case of a ++ text segment ending precisely at the end of a page; it causes the ++ data segment to skip a page. The above expression does not have ++ this problem, but it will currently (2/95) cause BFD to allocate ++ a single segment, combining both text and data, for this case. ++ This will prevent the text segment from being shared among ++ multiple executions of the program; I think that is more ++ important than losing a page of the virtual address space (note ++ that no actual memory is lost; the page which is skipped can not ++ be referenced). */ ++ . = .; ++ .data : ++ { ++ _fdata = . ; ++ *(.data) ++ ++ /* Put the compressed image here, so bss is on the end. */ ++ __image_begin = .; ++ *(.image) ++ __image_end = .; ++ /* Align the initial ramdisk image (INITRD) on page boundaries. */ ++ . = ALIGN(4096); ++ __ramdisk_begin = .; ++ *(.initrd) ++ __ramdisk_end = .; ++ . = ALIGN(4096); ++ ++ CONSTRUCTORS ++ } ++ .data1 : { *(.data1) } ++ _gp = . + 0x8000; ++ .lit8 : { *(.lit8) } ++ .lit4 : { *(.lit4) } ++ .ctors : { *(.ctors) } ++ .dtors : { *(.dtors) } ++ .got : { *(.got.plt) *(.got) } ++ .dynamic : { *(.dynamic) } ++ /* We want the small data sections together, so single-instruction offsets ++ can access them all, and initialized data all before uninitialized, so ++ we can shorten the on-disk segment size. */ ++ .sdata : { *(.sdata) } ++ . = ALIGN(4); ++ _edata = .; ++ PROVIDE (edata = .); ++ ++ __bss_start = .; ++ _fbss = .; ++ .sbss : { *(.sbss) *(.scommon) } ++ .bss : ++ { ++ *(.dynbss) ++ *(.bss) ++ *(COMMON) ++ . = ALIGN(4); ++ _end = . ; ++ PROVIDE (end = .); ++ } ++ ++ /* Sections to be discarded */ ++ /DISCARD/ : ++ { ++ *(.text.exit) ++ *(.data.exit) ++ *(.exitcall.exit) ++ } ++ ++ /* This is the MIPS specific mdebug section. */ ++ .mdebug : { *(.mdebug) } ++ /* These are needed for ELF backends which have not yet been ++ converted to the new style linker. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ /* DWARF debug sections. ++ Symbols in the .debug DWARF section are relative to the beginning of the ++ section so we begin .debug at 0. It's not clear yet what needs to happen ++ for the others. */ ++ .debug 0 : { *(.debug) } ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ .line 0 : { *(.line) } ++ /* These must appear regardless of . */ ++ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } ++ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } ++ .comment : { *(.comment) } ++ .note : { *(.note) } ++} +diff -Naru linux/arch/mips/zboot/lib/Makefile linux.spi/arch/mips/zboot/lib/Makefile +--- linux/arch/mips/zboot/lib/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/lib/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,9 @@ ++# ++# Makefile for some libs needed by zImage. ++# ++ ++L_TARGET := zlib.a ++ ++obj-y := zlib.o ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/lib/zlib.c linux.spi/arch/mips/zboot/lib/zlib.c +--- linux/arch/mips/zboot/lib/zlib.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/lib/zlib.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,2148 @@ ++/* ++ * This file is derived from various .h and .c files from the zlib-0.95 ++ * distribution by Jean-loup Gailly and Mark Adler, with some additions ++ * by Paul Mackerras to aid in implementing Deflate compression and ++ * decompression for PPP packets. See zlib.h for conditions of ++ * distribution and use. ++ * ++ * Changes that have been made include: ++ * - changed functions not used outside this file to "local" ++ * - added minCompression parameter to deflateInit2 ++ * - added Z_PACKET_FLUSH (see zlib.h for details) ++ * - added inflateIncomp ++ * ++ * $Id: zlib.c,v 1.2 2002/02/16 16:55:45 ppopov Exp $ ++ */ ++ ++/*+++++*/ ++/* zutil.h -- internal interface and configuration of the compression library ++ * Copyright (C) 1995 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ ++ ++#define _Z_UTIL_H ++ ++#include "zlib.h" ++ ++#ifndef local ++# define local static ++#endif ++/* compile with -Dlocal if your debugger can't find static symbols */ ++ ++#define FAR ++ ++typedef unsigned char uch; ++typedef uch FAR uchf; ++typedef unsigned short ush; ++typedef ush FAR ushf; ++typedef unsigned long ulg; ++ ++extern char *z_errmsg[]; /* indexed by 1-zlib_error */ ++ ++#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) ++/* To be used only when the state is known to be valid */ ++ ++#ifndef NULL ++#define NULL ((void *) 0) ++#endif ++ ++ /* common constants */ ++ ++#define DEFLATED 8 ++ ++#ifndef DEF_WBITS ++# define DEF_WBITS MAX_WBITS ++#endif ++/* default windowBits for decompression. MAX_WBITS is for compression only */ ++ ++#if MAX_MEM_LEVEL >= 8 ++# define DEF_MEM_LEVEL 8 ++#else ++# define DEF_MEM_LEVEL MAX_MEM_LEVEL ++#endif ++/* default memLevel */ ++ ++#define STORED_BLOCK 0 ++#define STATIC_TREES 1 ++#define DYN_TREES 2 ++/* The three kinds of block type */ ++ ++#define MIN_MATCH 3 ++#define MAX_MATCH 258 ++/* The minimum and maximum match lengths */ ++ ++ /* functions */ ++ ++#include <linux/string.h> ++#define zmemcpy memcpy ++#define zmemzero(dest, len) memset(dest, 0, len) ++ ++/* Diagnostic functions */ ++#ifdef DEBUG_ZLIB ++# include <stdio.h> ++# ifndef verbose ++# define verbose 0 ++# endif ++# define Assert(cond,msg) {if(!(cond)) z_error(msg);} ++# define Trace(x) fprintf x ++# define Tracev(x) {if (verbose) fprintf x ;} ++# define Tracevv(x) {if (verbose>1) fprintf x ;} ++# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} ++# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} ++#else ++# define Assert(cond,msg) ++# define Trace(x) ++# define Tracev(x) ++# define Tracevv(x) ++# define Tracec(c,x) ++# define Tracecv(c,x) ++#endif ++ ++ ++typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); ++ ++/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ ++/* void zcfree OF((voidpf opaque, voidpf ptr)); */ ++ ++#define ZALLOC(strm, items, size) \ ++ (*((strm)->zalloc))((strm)->opaque, (items), (size)) ++#define ZFREE(strm, addr, size) \ ++ (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) ++#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} ++ ++/* deflate.h -- internal compression state ++ * Copyright (C) 1995 Jean-loup Gailly ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/*+++++*/ ++/* infblock.h -- header to use infblock.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++struct inflate_blocks_state; ++typedef struct inflate_blocks_state FAR inflate_blocks_statef; ++ ++local inflate_blocks_statef * inflate_blocks_new OF(( ++ z_stream *z, ++ check_func c, /* check function */ ++ uInt w)); /* window size */ ++ ++local int inflate_blocks OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ int)); /* initial return code */ ++ ++local void inflate_blocks_reset OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ uLongf *)); /* check value on output */ ++ ++local int inflate_blocks_free OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ uLongf *)); /* check value on output */ ++ ++local int inflate_addhistory OF(( ++ inflate_blocks_statef *, ++ z_stream *)); ++ ++local int inflate_packet_flush OF(( ++ inflate_blocks_statef *)); ++ ++/*+++++*/ ++/* inftrees.h -- header to use inftrees.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* Huffman code lookup table entry--this entry is four bytes for machines ++ that have 16-bit pointers (e.g. PC's in the small or medium model). */ ++ ++typedef struct inflate_huft_s FAR inflate_huft; ++ ++struct inflate_huft_s { ++ union { ++ struct { ++ Byte Exop; /* number of extra bits or operation */ ++ Byte Bits; /* number of bits in this code or subcode */ ++ } what; ++ uInt Nalloc; /* number of these allocated here */ ++ Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ ++ } word; /* 16-bit, 8 bytes for 32-bit machines) */ ++ union { ++ uInt Base; /* literal, length base, or distance base */ ++ inflate_huft *Next; /* pointer to next level of table */ ++ } more; ++}; ++ ++#ifdef DEBUG_ZLIB ++ local uInt inflate_hufts; ++#endif ++ ++local int inflate_trees_bits OF(( ++ uIntf *, /* 19 code lengths */ ++ uIntf *, /* bits tree desired/actual depth */ ++ inflate_huft * FAR *, /* bits tree result */ ++ z_stream *)); /* for zalloc, zfree functions */ ++ ++local int inflate_trees_dynamic OF(( ++ uInt, /* number of literal/length codes */ ++ uInt, /* number of distance codes */ ++ uIntf *, /* that many (total) code lengths */ ++ uIntf *, /* literal desired/actual bit depth */ ++ uIntf *, /* distance desired/actual bit depth */ ++ inflate_huft * FAR *, /* literal/length tree result */ ++ inflate_huft * FAR *, /* distance tree result */ ++ z_stream *)); /* for zalloc, zfree functions */ ++ ++local int inflate_trees_fixed OF(( ++ uIntf *, /* literal desired/actual bit depth */ ++ uIntf *, /* distance desired/actual bit depth */ ++ inflate_huft * FAR *, /* literal/length tree result */ ++ inflate_huft * FAR *)); /* distance tree result */ ++ ++local int inflate_trees_free OF(( ++ inflate_huft *, /* tables to free */ ++ z_stream *)); /* for zfree function */ ++ ++ ++/*+++++*/ ++/* infcodes.h -- header to use infcodes.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++struct inflate_codes_state; ++typedef struct inflate_codes_state FAR inflate_codes_statef; ++ ++local inflate_codes_statef *inflate_codes_new OF(( ++ uInt, uInt, ++ inflate_huft *, inflate_huft *, ++ z_stream *)); ++ ++local int inflate_codes OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ int)); ++ ++local void inflate_codes_free OF(( ++ inflate_codes_statef *, ++ z_stream *)); ++ ++ ++/*+++++*/ ++/* inflate.c -- zlib interface to inflate modules ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* inflate private state */ ++struct internal_state { ++ ++ /* mode */ ++ enum { ++ METHOD, /* waiting for method byte */ ++ FLAG, /* waiting for flag byte */ ++ BLOCKS, /* decompressing blocks */ ++ CHECK4, /* four check bytes to go */ ++ CHECK3, /* three check bytes to go */ ++ CHECK2, /* two check bytes to go */ ++ CHECK1, /* one check byte to go */ ++ DONE, /* finished check, done */ ++ BAD} /* got an error--stay here */ ++ mode; /* current inflate mode */ ++ ++ /* mode dependent information */ ++ union { ++ uInt method; /* if FLAGS, method byte */ ++ struct { ++ uLong was; /* computed check value */ ++ uLong need; /* stream check value */ ++ } check; /* if CHECK, check values to compare */ ++ uInt marker; /* if BAD, inflateSync's marker bytes count */ ++ } sub; /* submode */ ++ ++ /* mode independent information */ ++ int nowrap; /* flag for no wrapper */ ++ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ ++ inflate_blocks_statef ++ *blocks; /* current inflate_blocks state */ ++ ++}; ++ ++ ++int inflateReset(z) ++z_stream *z; ++{ ++ uLong c; ++ ++ if (z == Z_NULL || z->state == Z_NULL) ++ return Z_STREAM_ERROR; ++ z->total_in = z->total_out = 0; ++ z->msg = Z_NULL; ++ z->state->mode = z->state->nowrap ? BLOCKS : METHOD; ++ inflate_blocks_reset(z->state->blocks, z, &c); ++ Trace((stderr, "inflate: reset\n")); ++ return Z_OK; ++} ++ ++ ++int inflateEnd(z) ++z_stream *z; ++{ ++ uLong c; ++ ++ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) ++ return Z_STREAM_ERROR; ++ if (z->state->blocks != Z_NULL) ++ inflate_blocks_free(z->state->blocks, z, &c); ++ ZFREE(z, z->state, sizeof(struct internal_state)); ++ z->state = Z_NULL; ++ Trace((stderr, "inflate: end\n")); ++ return Z_OK; ++} ++ ++ ++int inflateInit2(z, w) ++z_stream *z; ++int w; ++{ ++ /* initialize state */ ++ if (z == Z_NULL) ++ return Z_STREAM_ERROR; ++/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ ++/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ ++ if ((z->state = (struct internal_state FAR *) ++ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) ++ return Z_MEM_ERROR; ++ z->state->blocks = Z_NULL; ++ ++ /* handle undocumented nowrap option (no zlib header or check) */ ++ z->state->nowrap = 0; ++ if (w < 0) ++ { ++ w = - w; ++ z->state->nowrap = 1; ++ } ++ ++ /* set window size */ ++ if (w < 8 || w > 15) ++ { ++ inflateEnd(z); ++ return Z_STREAM_ERROR; ++ } ++ z->state->wbits = (uInt)w; ++ ++ /* create inflate_blocks state */ ++ if ((z->state->blocks = ++ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) ++ == Z_NULL) ++ { ++ inflateEnd(z); ++ return Z_MEM_ERROR; ++ } ++ Trace((stderr, "inflate: allocated\n")); ++ ++ /* reset state */ ++ inflateReset(z); ++ return Z_OK; ++} ++ ++ ++int inflateInit(z) ++z_stream *z; ++{ ++ return inflateInit2(z, DEF_WBITS); ++} ++ ++ ++#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} ++#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) ++ ++int inflate(z, f) ++z_stream *z; ++int f; ++{ ++ int r; ++ uInt b; ++ ++ if (z == Z_NULL || z->next_in == Z_NULL) ++ return Z_STREAM_ERROR; ++ r = Z_BUF_ERROR; ++ while (1) switch (z->state->mode) ++ { ++ case METHOD: ++ NEEDBYTE ++ if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) ++ { ++ z->state->mode = BAD; ++ z->msg = "unknown compression method"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ if ((z->state->sub.method >> 4) + 8 > z->state->wbits) ++ { ++ z->state->mode = BAD; ++ z->msg = "invalid window size"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ z->state->mode = FLAG; ++ case FLAG: ++ NEEDBYTE ++ if ((b = NEXTBYTE) & 0x20) ++ { ++ z->state->mode = BAD; ++ z->msg = "invalid reserved bit"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ if (((z->state->sub.method << 8) + b) % 31) ++ { ++ z->state->mode = BAD; ++ z->msg = "incorrect header check"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ Trace((stderr, "inflate: zlib header ok\n")); ++ z->state->mode = BLOCKS; ++ case BLOCKS: ++ r = inflate_blocks(z->state->blocks, z, r); ++ if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) ++ r = inflate_packet_flush(z->state->blocks); ++ if (r == Z_DATA_ERROR) ++ { ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; /* can try inflateSync */ ++ break; ++ } ++ if (r != Z_STREAM_END) ++ return r; ++ r = Z_OK; ++ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); ++ if (z->state->nowrap) ++ { ++ z->state->mode = DONE; ++ break; ++ } ++ z->state->mode = CHECK4; ++ case CHECK4: ++ NEEDBYTE ++ z->state->sub.check.need = (uLong)NEXTBYTE << 24; ++ z->state->mode = CHECK3; ++ case CHECK3: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 16; ++ z->state->mode = CHECK2; ++ case CHECK2: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 8; ++ z->state->mode = CHECK1; ++ case CHECK1: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE; ++ ++ if (z->state->sub.check.was != z->state->sub.check.need) ++ { ++ z->state->mode = BAD; ++ z->msg = "incorrect data check"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ Trace((stderr, "inflate: zlib check ok\n")); ++ z->state->mode = DONE; ++ case DONE: ++ return Z_STREAM_END; ++ case BAD: ++ return Z_DATA_ERROR; ++ default: ++ return Z_STREAM_ERROR; ++ } ++ ++ empty: ++ if (f != Z_PACKET_FLUSH) ++ return r; ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; /* can try inflateSync */ ++ return Z_DATA_ERROR; ++} ++ ++/* ++ * This subroutine adds the data at next_in/avail_in to the output history ++ * without performing any output. The output buffer must be "caught up"; ++ * i.e. no pending output (hence s->read equals s->write), and the state must ++ * be BLOCKS (i.e. we should be willing to see the start of a series of ++ * BLOCKS). On exit, the output will also be caught up, and the checksum ++ * will have been updated if need be. ++ */ ++ ++int inflateIncomp(z) ++z_stream *z; ++{ ++ if (z->state->mode != BLOCKS) ++ return Z_DATA_ERROR; ++ return inflate_addhistory(z->state->blocks, z); ++} ++ ++ ++int inflateSync(z) ++z_stream *z; ++{ ++ uInt n; /* number of bytes to look at */ ++ Bytef *p; /* pointer to bytes */ ++ uInt m; /* number of marker bytes found in a row */ ++ uLong r, w; /* temporaries to save total_in and total_out */ ++ ++ /* set up */ ++ if (z == Z_NULL || z->state == Z_NULL) ++ return Z_STREAM_ERROR; ++ if (z->state->mode != BAD) ++ { ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; ++ } ++ if ((n = z->avail_in) == 0) ++ return Z_BUF_ERROR; ++ p = z->next_in; ++ m = z->state->sub.marker; ++ ++ /* search */ ++ while (n && m < 4) ++ { ++ if (*p == (Byte)(m < 2 ? 0 : 0xff)) ++ m++; ++ else if (*p) ++ m = 0; ++ else ++ m = 4 - m; ++ p++, n--; ++ } ++ ++ /* restore */ ++ z->total_in += p - z->next_in; ++ z->next_in = p; ++ z->avail_in = n; ++ z->state->sub.marker = m; ++ ++ /* return no joy or set up to restart on a new block */ ++ if (m != 4) ++ return Z_DATA_ERROR; ++ r = z->total_in; w = z->total_out; ++ inflateReset(z); ++ z->total_in = r; z->total_out = w; ++ z->state->mode = BLOCKS; ++ return Z_OK; ++} ++ ++#undef NEEDBYTE ++#undef NEXTBYTE ++ ++/*+++++*/ ++/* infutil.h -- types and macros common to blocks and codes ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* inflate blocks semi-private state */ ++struct inflate_blocks_state { ++ ++ /* mode */ ++ enum { ++ TYPE, /* get type bits (3, including end bit) */ ++ LENS, /* get lengths for stored */ ++ STORED, /* processing stored block */ ++ TABLE, /* get table lengths */ ++ BTREE, /* get bit lengths tree for a dynamic block */ ++ DTREE, /* get length, distance trees for a dynamic block */ ++ CODES, /* processing fixed or dynamic block */ ++ DRY, /* output remaining window bytes */ ++ DONEB, /* finished last block, done */ ++ BADB} /* got a data error--stuck here */ ++ mode; /* current inflate_block mode */ ++ ++ /* mode dependent information */ ++ union { ++ uInt left; /* if STORED, bytes left to copy */ ++ struct { ++ uInt table; /* table lengths (14 bits) */ ++ uInt index; /* index into blens (or border) */ ++ uIntf *blens; /* bit lengths of codes */ ++ uInt bb; /* bit length tree depth */ ++ inflate_huft *tb; /* bit length decoding tree */ ++ int nblens; /* # elements allocated at blens */ ++ } trees; /* if DTREE, decoding info for trees */ ++ struct { ++ inflate_huft *tl, *td; /* trees to free */ ++ inflate_codes_statef ++ *codes; ++ } decode; /* if CODES, current state */ ++ } sub; /* submode */ ++ uInt last; /* true if this block is the last block */ ++ ++ /* mode independent information */ ++ uInt bitk; /* bits in bit buffer */ ++ uLong bitb; /* bit buffer */ ++ Bytef *window; /* sliding window */ ++ Bytef *end; /* one byte after sliding window */ ++ Bytef *read; /* window read pointer */ ++ Bytef *write; /* window write pointer */ ++ check_func checkfn; /* check function */ ++ uLong check; /* check on output */ ++ ++}; ++ ++ ++/* defines for inflate input/output */ ++/* update pointers and return */ ++#define UPDBITS {s->bitb=b;s->bitk=k;} ++#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} ++#define UPDOUT {s->write=q;} ++#define UPDATE {UPDBITS UPDIN UPDOUT} ++#define LEAVE {UPDATE return inflate_flush(s,z,r);} ++/* get bytes and bits */ ++#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} ++#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} ++#define NEXTBYTE (n--,*p++) ++#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} ++#define DUMPBITS(j) {b>>=(j);k-=(j);} ++/* output bytes */ ++#define WAVAIL (q<s->read?s->read-q-1:s->end-q) ++#define LOADOUT {q=s->write;m=WAVAIL;} ++#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} ++#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} ++#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} ++#define OUTBYTE(a) {*q++=(Byte)(a);m--;} ++/* load local pointers */ ++#define LOAD {LOADIN LOADOUT} ++ ++/* ++ * The IBM 150 firmware munges the data right after _etext[]. This ++ * protects it. -- Cort ++ */ ++local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; ++/* And'ing with mask[n] masks the lower n bits */ ++local uInt inflate_mask[] = { ++ 0x0000, ++ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, ++ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff ++}; ++ ++/* copy as much as possible from the sliding window to the output area */ ++local int inflate_flush OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ int)); ++ ++/*+++++*/ ++/* inffast.h -- header to use inffast.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++local int inflate_fast OF(( ++ uInt, ++ uInt, ++ inflate_huft *, ++ inflate_huft *, ++ inflate_blocks_statef *, ++ z_stream *)); ++ ++ ++/*+++++*/ ++/* infblock.c -- interpret and process block types to last block ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* Table for deflate from PKZIP's appnote.txt. */ ++local uInt border[] = { /* Order of the bit length code lengths */ ++ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; ++ ++/* ++ Notes beyond the 1.93a appnote.txt: ++ ++ 1. Distance pointers never point before the beginning of the output ++ stream. ++ 2. Distance pointers can point back across blocks, up to 32k away. ++ 3. There is an implied maximum of 7 bits for the bit length table and ++ 15 bits for the actual data. ++ 4. If only one code exists, then it is encoded using one bit. (Zero ++ would be more efficient, but perhaps a little confusing.) If two ++ codes exist, they are coded using one bit each (0 and 1). ++ 5. There is no way of sending zero distance codes--a dummy must be ++ sent if there are none. (History: a pre 2.0 version of PKZIP would ++ store blocks with no distance codes, but this was discovered to be ++ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow ++ zero distance codes, which is sent as one code of zero bits in ++ length. ++ 6. There are up to 286 literal/length codes. Code 256 represents the ++ end-of-block. Note however that the static length tree defines ++ 288 codes just to fill out the Huffman codes. Codes 286 and 287 ++ cannot be used though, since there is no length base or extra bits ++ defined for them. Similarily, there are up to 30 distance codes. ++ However, static trees define 32 codes (all 5 bits) to fill out the ++ Huffman codes, but the last two had better not show up in the data. ++ 7. Unzip can check dynamic Huffman blocks for complete code sets. ++ The exception is that a single code would not be complete (see #4). ++ 8. The five bits following the block type is really the number of ++ literal codes sent minus 257. ++ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits ++ (1+6+6). Therefore, to output three times the length, you output ++ three codes (1+1+1), whereas to output four times the same length, ++ you only need two codes (1+3). Hmm. ++ 10. In the tree reconstruction algorithm, Code = Code + Increment ++ only if BitLength(i) is not zero. (Pretty obvious.) ++ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) ++ 12. Note: length code 284 can represent 227-258, but length code 285 ++ really is 258. The last length deserves its own, short code ++ since it gets used a lot in very redundant files. The length ++ 258 is special since 258 - 3 (the min match length) is 255. ++ 13. The literal/length and distance code bit lengths are read as a ++ single stream of lengths. It is possible (and advantageous) for ++ a repeat code (16, 17, or 18) to go across the boundary between ++ the two sets of lengths. ++ */ ++ ++ ++local void inflate_blocks_reset(s, z, c) ++inflate_blocks_statef *s; ++z_stream *z; ++uLongf *c; ++{ ++ if (s->checkfn != Z_NULL) ++ *c = s->check; ++ if (s->mode == BTREE || s->mode == DTREE) ++ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); ++ if (s->mode == CODES) ++ { ++ inflate_codes_free(s->sub.decode.codes, z); ++ inflate_trees_free(s->sub.decode.td, z); ++ inflate_trees_free(s->sub.decode.tl, z); ++ } ++ s->mode = TYPE; ++ s->bitk = 0; ++ s->bitb = 0; ++ s->read = s->write = s->window; ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(0L, Z_NULL, 0); ++ Trace((stderr, "inflate: blocks reset\n")); ++} ++ ++ ++local inflate_blocks_statef *inflate_blocks_new(z, c, w) ++z_stream *z; ++check_func c; ++uInt w; ++{ ++ inflate_blocks_statef *s; ++ ++ if ((s = (inflate_blocks_statef *)ZALLOC ++ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) ++ return s; ++ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) ++ { ++ ZFREE(z, s, sizeof(struct inflate_blocks_state)); ++ return Z_NULL; ++ } ++ s->end = s->window + w; ++ s->checkfn = c; ++ s->mode = TYPE; ++ Trace((stderr, "inflate: blocks allocated\n")); ++ inflate_blocks_reset(s, z, &s->check); ++ return s; ++} ++ ++ ++local int inflate_blocks(s, z, r) ++inflate_blocks_statef *s; ++z_stream *z; ++int r; ++{ ++ uInt t; /* temporary storage */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ ++ /* copy input/output information to locals (UPDATE macro restores) */ ++ LOAD ++ ++ /* process input based on current state */ ++ while (1) switch (s->mode) ++ { ++ case TYPE: ++ NEEDBITS(3) ++ t = (uInt)b & 7; ++ s->last = t & 1; ++ switch (t >> 1) ++ { ++ case 0: /* stored */ ++ Trace((stderr, "inflate: stored block%s\n", ++ s->last ? " (last)" : "")); ++ DUMPBITS(3) ++ t = k & 7; /* go to byte boundary */ ++ DUMPBITS(t) ++ s->mode = LENS; /* get length of stored block */ ++ break; ++ case 1: /* fixed */ ++ Trace((stderr, "inflate: fixed codes block%s\n", ++ s->last ? " (last)" : "")); ++ { ++ uInt bl, bd; ++ inflate_huft *tl, *td; ++ ++ inflate_trees_fixed(&bl, &bd, &tl, &td); ++ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); ++ if (s->sub.decode.codes == Z_NULL) ++ { ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ s->sub.decode.tl = Z_NULL; /* don't try to free these */ ++ s->sub.decode.td = Z_NULL; ++ } ++ DUMPBITS(3) ++ s->mode = CODES; ++ break; ++ case 2: /* dynamic */ ++ Trace((stderr, "inflate: dynamic codes block%s\n", ++ s->last ? " (last)" : "")); ++ DUMPBITS(3) ++ s->mode = TABLE; ++ break; ++ case 3: /* illegal */ ++ DUMPBITS(3) ++ s->mode = BADB; ++ z->msg = "invalid block type"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ break; ++ case LENS: ++ NEEDBITS(32) ++ if (((~b) >> 16) != (b & 0xffff)) ++ { ++ s->mode = BADB; ++ z->msg = "invalid stored block lengths"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ s->sub.left = (uInt)b & 0xffff; ++ b = k = 0; /* dump bits */ ++ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); ++ s->mode = s->sub.left ? STORED : TYPE; ++ break; ++ case STORED: ++ if (n == 0) ++ LEAVE ++ NEEDOUT ++ t = s->sub.left; ++ if (t > n) t = n; ++ if (t > m) t = m; ++ zmemcpy(q, p, t); ++ p += t; n -= t; ++ q += t; m -= t; ++ if ((s->sub.left -= t) != 0) ++ break; ++ Tracev((stderr, "inflate: stored end, %lu total out\n", ++ z->total_out + (q >= s->read ? q - s->read : ++ (s->end - s->read) + (q - s->window)))); ++ s->mode = s->last ? DRY : TYPE; ++ break; ++ case TABLE: ++ NEEDBITS(14) ++ s->sub.trees.table = t = (uInt)b & 0x3fff; ++#ifndef PKZIP_BUG_WORKAROUND ++ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) ++ { ++ s->mode = BADB; ++ z->msg = "too many length or distance symbols"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++#endif ++ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); ++ if (t < 19) ++ t = 19; ++ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) ++ { ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ s->sub.trees.nblens = t; ++ DUMPBITS(14) ++ s->sub.trees.index = 0; ++ Tracev((stderr, "inflate: table sizes ok\n")); ++ s->mode = BTREE; ++ case BTREE: ++ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) ++ { ++ NEEDBITS(3) ++ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; ++ DUMPBITS(3) ++ } ++ while (s->sub.trees.index < 19) ++ s->sub.trees.blens[border[s->sub.trees.index++]] = 0; ++ s->sub.trees.bb = 7; ++ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, ++ &s->sub.trees.tb, z); ++ if (t != Z_OK) ++ { ++ r = t; ++ if (r == Z_DATA_ERROR) ++ s->mode = BADB; ++ LEAVE ++ } ++ s->sub.trees.index = 0; ++ Tracev((stderr, "inflate: bits tree ok\n")); ++ s->mode = DTREE; ++ case DTREE: ++ while (t = s->sub.trees.table, ++ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) ++ { ++ inflate_huft *h; ++ uInt i, j, c; ++ ++ t = s->sub.trees.bb; ++ NEEDBITS(t) ++ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); ++ t = h->word.what.Bits; ++ c = h->more.Base; ++ if (c < 16) ++ { ++ DUMPBITS(t) ++ s->sub.trees.blens[s->sub.trees.index++] = c; ++ } ++ else /* c == 16..18 */ ++ { ++ i = c == 18 ? 7 : c - 14; ++ j = c == 18 ? 11 : 3; ++ NEEDBITS(t + i) ++ DUMPBITS(t) ++ j += (uInt)b & inflate_mask[i]; ++ DUMPBITS(i) ++ i = s->sub.trees.index; ++ t = s->sub.trees.table; ++ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || ++ (c == 16 && i < 1)) ++ { ++ s->mode = BADB; ++ z->msg = "invalid bit length repeat"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ c = c == 16 ? s->sub.trees.blens[i - 1] : 0; ++ do { ++ s->sub.trees.blens[i++] = c; ++ } while (--j); ++ s->sub.trees.index = i; ++ } ++ } ++ inflate_trees_free(s->sub.trees.tb, z); ++ s->sub.trees.tb = Z_NULL; ++ { ++ uInt bl, bd; ++ inflate_huft *tl, *td; ++ inflate_codes_statef *c; ++ ++ bl = 9; /* must be <= 9 for lookahead assumptions */ ++ bd = 6; /* must be <= 9 for lookahead assumptions */ ++ t = s->sub.trees.table; ++ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), ++ s->sub.trees.blens, &bl, &bd, &tl, &td, z); ++ if (t != Z_OK) ++ { ++ if (t == (uInt)Z_DATA_ERROR) ++ s->mode = BADB; ++ r = t; ++ LEAVE ++ } ++ Tracev((stderr, "inflate: trees ok\n")); ++ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) ++ { ++ inflate_trees_free(td, z); ++ inflate_trees_free(tl, z); ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); ++ s->sub.decode.codes = c; ++ s->sub.decode.tl = tl; ++ s->sub.decode.td = td; ++ } ++ s->mode = CODES; ++ case CODES: ++ UPDATE ++ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) ++ return inflate_flush(s, z, r); ++ r = Z_OK; ++ inflate_codes_free(s->sub.decode.codes, z); ++ inflate_trees_free(s->sub.decode.td, z); ++ inflate_trees_free(s->sub.decode.tl, z); ++ LOAD ++ Tracev((stderr, "inflate: codes end, %lu total out\n", ++ z->total_out + (q >= s->read ? q - s->read : ++ (s->end - s->read) + (q - s->window)))); ++ if (!s->last) ++ { ++ s->mode = TYPE; ++ break; ++ } ++ if (k > 7) /* return unused byte, if any */ ++ { ++ Assert(k < 16, "inflate_codes grabbed too many bytes") ++ k -= 8; ++ n++; ++ p--; /* can always return one */ ++ } ++ s->mode = DRY; ++ case DRY: ++ FLUSH ++ if (s->read != s->write) ++ LEAVE ++ s->mode = DONEB; ++ case DONEB: ++ r = Z_STREAM_END; ++ LEAVE ++ case BADB: ++ r = Z_DATA_ERROR; ++ LEAVE ++ default: ++ r = Z_STREAM_ERROR; ++ LEAVE ++ } ++} ++ ++ ++local int inflate_blocks_free(s, z, c) ++inflate_blocks_statef *s; ++z_stream *z; ++uLongf *c; ++{ ++ inflate_blocks_reset(s, z, c); ++ ZFREE(z, s->window, s->end - s->window); ++ ZFREE(z, s, sizeof(struct inflate_blocks_state)); ++ Trace((stderr, "inflate: blocks freed\n")); ++ return Z_OK; ++} ++ ++/* ++ * This subroutine adds the data at next_in/avail_in to the output history ++ * without performing any output. The output buffer must be "caught up"; ++ * i.e. no pending output (hence s->read equals s->write), and the state must ++ * be BLOCKS (i.e. we should be willing to see the start of a series of ++ * BLOCKS). On exit, the output will also be caught up, and the checksum ++ * will have been updated if need be. ++ */ ++local int inflate_addhistory(s, z) ++inflate_blocks_statef *s; ++z_stream *z; ++{ ++ uLong b; /* bit buffer */ /* NOT USED HERE */ ++ uInt k; /* bits in bit buffer */ /* NOT USED HERE */ ++ uInt t; /* temporary storage */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ ++ if (s->read != s->write) ++ return Z_STREAM_ERROR; ++ if (s->mode != TYPE) ++ return Z_DATA_ERROR; ++ ++ /* we're ready to rock */ ++ LOAD ++ /* while there is input ready, copy to output buffer, moving ++ * pointers as needed. ++ */ ++ while (n) { ++ t = n; /* how many to do */ ++ /* is there room until end of buffer? */ ++ if (t > m) t = m; ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(s->check, q, t); ++ zmemcpy(q, p, t); ++ q += t; ++ p += t; ++ n -= t; ++ z->total_out += t; ++ s->read = q; /* drag read pointer forward */ ++/* WRAP */ /* expand WRAP macro by hand to handle s->read */ ++ if (q == s->end) { ++ s->read = q = s->window; ++ m = WAVAIL; ++ } ++ } ++ UPDATE ++ return Z_OK; ++} ++ ++ ++/* ++ * At the end of a Deflate-compressed PPP packet, we expect to have seen ++ * a `stored' block type value but not the (zero) length bytes. ++ */ ++local int inflate_packet_flush(s) ++ inflate_blocks_statef *s; ++{ ++ if (s->mode != LENS) ++ return Z_DATA_ERROR; ++ s->mode = TYPE; ++ return Z_OK; ++} ++ ++ ++/*+++++*/ ++/* inftrees.c -- generate Huffman trees for efficient decoding ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define base more.Base ++#define next more.Next ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++ ++local int huft_build OF(( ++ uIntf *, /* code lengths in bits */ ++ uInt, /* number of codes */ ++ uInt, /* number of "simple" codes */ ++ uIntf *, /* list of base values for non-simple codes */ ++ uIntf *, /* list of extra bits for non-simple codes */ ++ inflate_huft * FAR*,/* result: starting table */ ++ uIntf *, /* maximum lookup bits (returns actual) */ ++ z_stream *)); /* for zalloc function */ ++ ++local voidpf falloc OF(( ++ voidpf, /* opaque pointer (not used) */ ++ uInt, /* number of items */ ++ uInt)); /* size of item */ ++ ++local void ffree OF(( ++ voidpf q, /* opaque pointer (not used) */ ++ voidpf p, /* what to free (not used) */ ++ uInt n)); /* number of bytes (not used) */ ++ ++/* Tables for deflate from PKZIP's appnote.txt. */ ++local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ ++ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, ++ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; ++ /* actually lengths - 2; also see note #13 above about 258 */ ++local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, ++ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ ++local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ ++ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, ++ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, ++ 8193, 12289, 16385, 24577}; ++local uInt cpdext[] = { /* Extra bits for distance codes */ ++ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, ++ 12, 12, 13, 13}; ++ ++/* ++ Huffman code decoding is performed using a multi-level table lookup. ++ The fastest way to decode is to simply build a lookup table whose ++ size is determined by the longest code. However, the time it takes ++ to build this table can also be a factor if the data being decoded ++ is not very long. The most common codes are necessarily the ++ shortest codes, so those codes dominate the decoding time, and hence ++ the speed. The idea is you can have a shorter table that decodes the ++ shorter, more probable codes, and then point to subsidiary tables for ++ the longer codes. The time it costs to decode the longer codes is ++ then traded against the time it takes to make longer tables. ++ ++ This results of this trade are in the variables lbits and dbits ++ below. lbits is the number of bits the first level table for literal/ ++ length codes can decode in one step, and dbits is the same thing for ++ the distance codes. Subsequent tables are also less than or equal to ++ those sizes. These values may be adjusted either when all of the ++ codes are shorter than that, in which case the longest code length in ++ bits is used, or when the shortest code is *longer* than the requested ++ table size, in which case the length of the shortest code in bits is ++ used. ++ ++ There are two different values for the two tables, since they code a ++ different number of possibilities each. The literal/length table ++ codes 286 possible values, or in a flat code, a little over eight ++ bits. The distance table codes 30 possible values, or a little less ++ than five bits, flat. The optimum values for speed end up being ++ about one bit more than those, so lbits is 8+1 and dbits is 5+1. ++ The optimum values may differ though from machine to machine, and ++ possibly even between compilers. Your mileage may vary. ++ */ ++ ++ ++/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ ++#define BMAX 15 /* maximum bit length of any code */ ++#define N_MAX 288 /* maximum number of codes in any set */ ++ ++#ifdef DEBUG_ZLIB ++ uInt inflate_hufts; ++#endif ++ ++local int huft_build(b, n, s, d, e, t, m, zs) ++uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ ++uInt n; /* number of codes (assumed <= N_MAX) */ ++uInt s; /* number of simple-valued codes (0..s-1) */ ++uIntf *d; /* list of base values for non-simple codes */ ++uIntf *e; /* list of extra bits for non-simple codes */ ++inflate_huft * FAR *t; /* result: starting table */ ++uIntf *m; /* maximum lookup bits, returns actual */ ++z_stream *zs; /* for zalloc function */ ++/* Given a list of code lengths and a maximum table size, make a set of ++ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR ++ if the given code set is incomplete (the tables are still built in this ++ case), Z_DATA_ERROR if the input is invalid (all zero length codes or an ++ over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ ++{ ++ ++ uInt a; /* counter for codes of length k */ ++ uInt c[BMAX+1]; /* bit length count table */ ++ uInt f; /* i repeats in table every f entries */ ++ int g; /* maximum code length */ ++ int h; /* table level */ ++ register uInt i; /* counter, current code */ ++ register uInt j; /* counter */ ++ register int k; /* number of bits in current code */ ++ int l; /* bits per table (returned in m) */ ++ register uIntf *p; /* pointer into c[], b[], or v[] */ ++ inflate_huft *q; /* points to current table */ ++ struct inflate_huft_s r; /* table entry for structure assignment */ ++ inflate_huft *u[BMAX]; /* table stack */ ++ uInt v[N_MAX]; /* values in order of bit length */ ++ register int w; /* bits before this table == (l * h) */ ++ uInt x[BMAX+1]; /* bit offsets, then code stack */ ++ uIntf *xp; /* pointer into x */ ++ int y; /* number of dummy codes added */ ++ uInt z; /* number of entries in current table */ ++ ++ ++ /* Generate counts for each bit length */ ++ p = c; ++#define C0 *p++ = 0; ++#define C2 C0 C0 C0 C0 ++#define C4 C2 C2 C2 C2 ++ C4 /* clear c[]--assume BMAX+1 is 16 */ ++ p = b; i = n; ++ do { ++ c[*p++]++; /* assume all entries <= BMAX */ ++ } while (--i); ++ if (c[0] == n) /* null input--all zero length codes */ ++ { ++ *t = (inflate_huft *)Z_NULL; ++ *m = 0; ++ return Z_OK; ++ } ++ ++ ++ /* Find minimum and maximum length, bound *m by those */ ++ l = *m; ++ for (j = 1; j <= BMAX; j++) ++ if (c[j]) ++ break; ++ k = j; /* minimum code length */ ++ if ((uInt)l < j) ++ l = j; ++ for (i = BMAX; i; i--) ++ if (c[i]) ++ break; ++ g = i; /* maximum code length */ ++ if ((uInt)l > i) ++ l = i; ++ *m = l; ++ ++ ++ /* Adjust last length count to fill out codes, if needed */ ++ for (y = 1 << j; j < i; j++, y <<= 1) ++ if ((y -= c[j]) < 0) ++ return Z_DATA_ERROR; ++ if ((y -= c[i]) < 0) ++ return Z_DATA_ERROR; ++ c[i] += y; ++ ++ ++ /* Generate starting offsets into the value table for each length */ ++ x[1] = j = 0; ++ p = c + 1; xp = x + 2; ++ while (--i) { /* note that i == g from above */ ++ *xp++ = (j += *p++); ++ } ++ ++ ++ /* Make a table of values in order of bit lengths */ ++ p = b; i = 0; ++ do { ++ if ((j = *p++) != 0) ++ v[x[j]++] = i; ++ } while (++i < n); ++ ++ ++ /* Generate the Huffman codes and for each, make the table entries */ ++ x[0] = i = 0; /* first Huffman code is zero */ ++ p = v; /* grab values in bit order */ ++ h = -1; /* no tables yet--level -1 */ ++ w = -l; /* bits decoded == (l * h) */ ++ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ ++ q = (inflate_huft *)Z_NULL; /* ditto */ ++ z = 0; /* ditto */ ++ ++ /* go through the bit lengths (k already is bits in shortest code) */ ++ for (; k <= g; k++) ++ { ++ a = c[k]; ++ while (a--) ++ { ++ /* here i is the Huffman code of length k bits for value *p */ ++ /* make tables up to required level */ ++ while (k > w + l) ++ { ++ h++; ++ w += l; /* previous table always l bits */ ++ ++ /* compute minimum size table less than or equal to l bits */ ++ z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ ++ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ ++ { /* too few codes for k-w bit table */ ++ f -= a + 1; /* deduct codes from patterns left */ ++ xp = c + k; ++ if (j < z) ++ while (++j < z) /* try smaller tables up to z bits */ ++ { ++ if ((f <<= 1) <= *++xp) ++ break; /* enough codes to use up j bits */ ++ f -= *xp; /* else deduct codes from patterns */ ++ } ++ } ++ z = 1 << j; /* table entries for j-bit table */ ++ ++ /* allocate and link in new table */ ++ if ((q = (inflate_huft *)ZALLOC ++ (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) ++ { ++ if (h) ++ inflate_trees_free(u[0], zs); ++ return Z_MEM_ERROR; /* not enough memory */ ++ } ++ q->word.Nalloc = z + 1; ++#ifdef DEBUG_ZLIB ++ inflate_hufts += z + 1; ++#endif ++ *t = q + 1; /* link to list for huft_free() */ ++ *(t = &(q->next)) = Z_NULL; ++ u[h] = ++q; /* table starts after link */ ++ ++ /* connect to last table, if there is one */ ++ if (h) ++ { ++ x[h] = i; /* save pattern for backing up */ ++ r.bits = (Byte)l; /* bits to dump before this table */ ++ r.exop = (Byte)j; /* bits in this table */ ++ r.next = q; /* pointer to this table */ ++ j = i >> (w - l); /* (get around Turbo C bug) */ ++ u[h-1][j] = r; /* connect to last table */ ++ } ++ } ++ ++ /* set up table entry in r */ ++ r.bits = (Byte)(k - w); ++ if (p >= v + n) ++ r.exop = 128 + 64; /* out of values--invalid code */ ++ else if (*p < s) ++ { ++ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ ++ r.base = *p++; /* simple code is just the value */ ++ } ++ else ++ { ++ r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ ++ r.base = d[*p++ - s]; ++ } ++ ++ /* fill code-like entries with r */ ++ f = 1 << (k - w); ++ for (j = i >> w; j < z; j += f) ++ q[j] = r; ++ ++ /* backwards increment the k-bit code i */ ++ for (j = 1 << (k - 1); i & j; j >>= 1) ++ i ^= j; ++ i ^= j; ++ ++ /* backup over finished tables */ ++ while ((i & ((1 << w) - 1)) != x[h]) ++ { ++ h--; /* don't need to update q */ ++ w -= l; ++ } ++ } ++ } ++ ++ ++ /* Return Z_BUF_ERROR if we were given an incomplete table */ ++ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; ++} ++ ++ ++local int inflate_trees_bits(c, bb, tb, z) ++uIntf *c; /* 19 code lengths */ ++uIntf *bb; /* bits tree desired/actual depth */ ++inflate_huft * FAR *tb; /* bits tree result */ ++z_stream *z; /* for zfree function */ ++{ ++ int r; ++ ++ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); ++ if (r == Z_DATA_ERROR) ++ z->msg = "oversubscribed dynamic bit lengths tree"; ++ else if (r == Z_BUF_ERROR) ++ { ++ inflate_trees_free(*tb, z); ++ z->msg = "incomplete dynamic bit lengths tree"; ++ r = Z_DATA_ERROR; ++ } ++ return r; ++} ++ ++ ++local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) ++uInt nl; /* number of literal/length codes */ ++uInt nd; /* number of distance codes */ ++uIntf *c; /* that many (total) code lengths */ ++uIntf *bl; /* literal desired/actual bit depth */ ++uIntf *bd; /* distance desired/actual bit depth */ ++inflate_huft * FAR *tl; /* literal/length tree result */ ++inflate_huft * FAR *td; /* distance tree result */ ++z_stream *z; /* for zfree function */ ++{ ++ int r; ++ ++ /* build literal/length tree */ ++ if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) ++ { ++ if (r == Z_DATA_ERROR) ++ z->msg = "oversubscribed literal/length tree"; ++ else if (r == Z_BUF_ERROR) ++ { ++ inflate_trees_free(*tl, z); ++ z->msg = "incomplete literal/length tree"; ++ r = Z_DATA_ERROR; ++ } ++ return r; ++ } ++ ++ /* build distance tree */ ++ if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) ++ { ++ if (r == Z_DATA_ERROR) ++ z->msg = "oversubscribed literal/length tree"; ++ else if (r == Z_BUF_ERROR) { ++#ifdef PKZIP_BUG_WORKAROUND ++ r = Z_OK; ++ } ++#else ++ inflate_trees_free(*td, z); ++ z->msg = "incomplete literal/length tree"; ++ r = Z_DATA_ERROR; ++ } ++ inflate_trees_free(*tl, z); ++ return r; ++#endif ++ } ++ ++ /* done */ ++ return Z_OK; ++} ++ ++ ++/* build fixed tables only once--keep them here */ ++local int fixed_lock = 0; ++local int fixed_built = 0; ++#define FIXEDH 530 /* number of hufts used by fixed tables */ ++local uInt fixed_left = FIXEDH; ++local inflate_huft fixed_mem[FIXEDH]; ++local uInt fixed_bl; ++local uInt fixed_bd; ++local inflate_huft *fixed_tl; ++local inflate_huft *fixed_td; ++ ++ ++local voidpf falloc(q, n, s) ++voidpf q; /* opaque pointer (not used) */ ++uInt n; /* number of items */ ++uInt s; /* size of item */ ++{ ++ Assert(s == sizeof(inflate_huft) && n <= fixed_left, ++ "inflate_trees falloc overflow"); ++ if (q) s++; /* to make some compilers happy */ ++ fixed_left -= n; ++ return (voidpf)(fixed_mem + fixed_left); ++} ++ ++ ++local void ffree(q, p, n) ++voidpf q; ++voidpf p; ++uInt n; ++{ ++ Assert(0, "inflate_trees ffree called!"); ++ if (q) q = p; /* to make some compilers happy */ ++} ++ ++ ++local int inflate_trees_fixed(bl, bd, tl, td) ++uIntf *bl; /* literal desired/actual bit depth */ ++uIntf *bd; /* distance desired/actual bit depth */ ++inflate_huft * FAR *tl; /* literal/length tree result */ ++inflate_huft * FAR *td; /* distance tree result */ ++{ ++ /* build fixed tables if not built already--lock out other instances */ ++ while (++fixed_lock > 1) ++ fixed_lock--; ++ if (!fixed_built) ++ { ++ int k; /* temporary variable */ ++ unsigned c[288]; /* length list for huft_build */ ++ z_stream z; /* for falloc function */ ++ ++ /* set up fake z_stream for memory routines */ ++ z.zalloc = falloc; ++ z.zfree = ffree; ++ z.opaque = Z_NULL; ++ ++ /* literal table */ ++ for (k = 0; k < 144; k++) ++ c[k] = 8; ++ for (; k < 256; k++) ++ c[k] = 9; ++ for (; k < 280; k++) ++ c[k] = 7; ++ for (; k < 288; k++) ++ c[k] = 8; ++ fixed_bl = 7; ++ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); ++ ++ /* distance table */ ++ for (k = 0; k < 30; k++) ++ c[k] = 5; ++ fixed_bd = 5; ++ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); ++ ++ /* done */ ++ fixed_built = 1; ++ } ++ fixed_lock--; ++ *bl = fixed_bl; ++ *bd = fixed_bd; ++ *tl = fixed_tl; ++ *td = fixed_td; ++ return Z_OK; ++} ++ ++ ++local int inflate_trees_free(t, z) ++inflate_huft *t; /* table to free */ ++z_stream *z; /* for zfree function */ ++/* Free the malloc'ed tables built by huft_build(), which makes a linked ++ list of the tables it made, with the links in a dummy first entry of ++ each table. */ ++{ ++ register inflate_huft *p, *q; ++ ++ /* Go through linked list, freeing from the malloced (t[-1]) address. */ ++ p = t; ++ while (p != Z_NULL) ++ { ++ q = (--p)->next; ++ ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); ++ p = q; ++ } ++ return Z_OK; ++} ++ ++/*+++++*/ ++/* infcodes.c -- process literals and length/distance pairs ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define base more.Base ++#define next more.Next ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++/* inflate codes private state */ ++struct inflate_codes_state { ++ ++ /* mode */ ++ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ ++ START, /* x: set up for LEN */ ++ LEN, /* i: get length/literal/eob next */ ++ LENEXT, /* i: getting length extra (have base) */ ++ DIST, /* i: get distance next */ ++ DISTEXT, /* i: getting distance extra */ ++ COPY, /* o: copying bytes in window, waiting for space */ ++ LIT, /* o: got literal, waiting for output space */ ++ WASH, /* o: got eob, possibly still output waiting */ ++ END, /* x: got eob and all data flushed */ ++ BADCODE} /* x: got error */ ++ mode; /* current inflate_codes mode */ ++ ++ /* mode dependent information */ ++ uInt len; ++ union { ++ struct { ++ inflate_huft *tree; /* pointer into tree */ ++ uInt need; /* bits needed */ ++ } code; /* if LEN or DIST, where in tree */ ++ uInt lit; /* if LIT, literal */ ++ struct { ++ uInt get; /* bits to get for extra */ ++ uInt dist; /* distance back to copy from */ ++ } copy; /* if EXT or COPY, where and how much */ ++ } sub; /* submode */ ++ ++ /* mode independent information */ ++ Byte lbits; /* ltree bits decoded per branch */ ++ Byte dbits; /* dtree bits decoder per branch */ ++ inflate_huft *ltree; /* literal/length/eob tree */ ++ inflate_huft *dtree; /* distance tree */ ++ ++}; ++ ++ ++local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) ++uInt bl, bd; ++inflate_huft *tl, *td; ++z_stream *z; ++{ ++ inflate_codes_statef *c; ++ ++ if ((c = (inflate_codes_statef *) ++ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) ++ { ++ c->mode = START; ++ c->lbits = (Byte)bl; ++ c->dbits = (Byte)bd; ++ c->ltree = tl; ++ c->dtree = td; ++ Tracev((stderr, "inflate: codes new\n")); ++ } ++ return c; ++} ++ ++ ++local int inflate_codes(s, z, r) ++inflate_blocks_statef *s; ++z_stream *z; ++int r; ++{ ++ uInt j; /* temporary storage */ ++ inflate_huft *t; /* temporary pointer */ ++ uInt e; /* extra bits or operation */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ Bytef *f; /* pointer to copy strings from */ ++ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ ++ ++ /* copy input/output information to locals (UPDATE macro restores) */ ++ LOAD ++ ++ /* process input and output based on current state */ ++ while (1) switch (c->mode) ++ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ ++ case START: /* x: set up for LEN */ ++#ifndef SLOW ++ if (m >= 258 && n >= 10) ++ { ++ UPDATE ++ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); ++ LOAD ++ if (r != Z_OK) ++ { ++ c->mode = r == Z_STREAM_END ? WASH : BADCODE; ++ break; ++ } ++ } ++#endif /* !SLOW */ ++ c->sub.code.need = c->lbits; ++ c->sub.code.tree = c->ltree; ++ c->mode = LEN; ++ case LEN: /* i: get length/literal/eob next */ ++ j = c->sub.code.need; ++ NEEDBITS(j) ++ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); ++ DUMPBITS(t->bits) ++ e = (uInt)(t->exop); ++ if (e == 0) /* literal */ ++ { ++ c->sub.lit = t->base; ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: literal '%c'\n" : ++ "inflate: literal 0x%02x\n", t->base)); ++ c->mode = LIT; ++ break; ++ } ++ if (e & 16) /* length */ ++ { ++ c->sub.copy.get = e & 15; ++ c->len = t->base; ++ c->mode = LENEXT; ++ break; ++ } ++ if ((e & 64) == 0) /* next table */ ++ { ++ c->sub.code.need = e; ++ c->sub.code.tree = t->next; ++ break; ++ } ++ if (e & 32) /* end of block */ ++ { ++ Tracevv((stderr, "inflate: end of block\n")); ++ c->mode = WASH; ++ break; ++ } ++ c->mode = BADCODE; /* invalid code */ ++ z->msg = "invalid literal/length code"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ case LENEXT: /* i: getting length extra (have base) */ ++ j = c->sub.copy.get; ++ NEEDBITS(j) ++ c->len += (uInt)b & inflate_mask[j]; ++ DUMPBITS(j) ++ c->sub.code.need = c->dbits; ++ c->sub.code.tree = c->dtree; ++ Tracevv((stderr, "inflate: length %u\n", c->len)); ++ c->mode = DIST; ++ case DIST: /* i: get distance next */ ++ j = c->sub.code.need; ++ NEEDBITS(j) ++ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); ++ DUMPBITS(t->bits) ++ e = (uInt)(t->exop); ++ if (e & 16) /* distance */ ++ { ++ c->sub.copy.get = e & 15; ++ c->sub.copy.dist = t->base; ++ c->mode = DISTEXT; ++ break; ++ } ++ if ((e & 64) == 0) /* next table */ ++ { ++ c->sub.code.need = e; ++ c->sub.code.tree = t->next; ++ break; ++ } ++ c->mode = BADCODE; /* invalid code */ ++ z->msg = "invalid distance code"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ case DISTEXT: /* i: getting distance extra */ ++ j = c->sub.copy.get; ++ NEEDBITS(j) ++ c->sub.copy.dist += (uInt)b & inflate_mask[j]; ++ DUMPBITS(j) ++ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); ++ c->mode = COPY; ++ case COPY: /* o: copying bytes in window, waiting for space */ ++#ifndef __TURBOC__ /* Turbo C bug for following expression */ ++ f = (uInt)(q - s->window) < c->sub.copy.dist ? ++ s->end - (c->sub.copy.dist - (q - s->window)) : ++ q - c->sub.copy.dist; ++#else ++ f = q - c->sub.copy.dist; ++ if ((uInt)(q - s->window) < c->sub.copy.dist) ++ f = s->end - (c->sub.copy.dist - (q - s->window)); ++#endif ++ while (c->len) ++ { ++ NEEDOUT ++ OUTBYTE(*f++) ++ if (f == s->end) ++ f = s->window; ++ c->len--; ++ } ++ c->mode = START; ++ break; ++ case LIT: /* o: got literal, waiting for output space */ ++ NEEDOUT ++ OUTBYTE(c->sub.lit) ++ c->mode = START; ++ break; ++ case WASH: /* o: got eob, possibly more output */ ++ FLUSH ++ if (s->read != s->write) ++ LEAVE ++ c->mode = END; ++ case END: ++ r = Z_STREAM_END; ++ LEAVE ++ case BADCODE: /* x: got error */ ++ r = Z_DATA_ERROR; ++ LEAVE ++ default: ++ r = Z_STREAM_ERROR; ++ LEAVE ++ } ++} ++ ++ ++local void inflate_codes_free(c, z) ++inflate_codes_statef *c; ++z_stream *z; ++{ ++ ZFREE(z, c, sizeof(struct inflate_codes_state)); ++ Tracev((stderr, "inflate: codes free\n")); ++} ++ ++/*+++++*/ ++/* inflate_util.c -- data and routines common to blocks and codes ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* copy as much as possible from the sliding window to the output area */ ++local int inflate_flush(s, z, r) ++inflate_blocks_statef *s; ++z_stream *z; ++int r; ++{ ++ uInt n; ++ Bytef *p, *q; ++ ++ /* local copies of source and destination pointers */ ++ p = z->next_out; ++ q = s->read; ++ ++ /* compute number of bytes to copy as far as end of window */ ++ n = (uInt)((q <= s->write ? s->write : s->end) - q); ++ if (n > z->avail_out) n = z->avail_out; ++ if (n && r == Z_BUF_ERROR) r = Z_OK; ++ ++ /* update counters */ ++ z->avail_out -= n; ++ z->total_out += n; ++ ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(s->check, q, n); ++ ++ /* copy as far as end of window */ ++ zmemcpy(p, q, n); ++ p += n; ++ q += n; ++ ++ /* see if more to copy at beginning of window */ ++ if (q == s->end) ++ { ++ /* wrap pointers */ ++ q = s->window; ++ if (s->write == s->end) ++ s->write = s->window; ++ ++ /* compute bytes to copy */ ++ n = (uInt)(s->write - q); ++ if (n > z->avail_out) n = z->avail_out; ++ if (n && r == Z_BUF_ERROR) r = Z_OK; ++ ++ /* update counters */ ++ z->avail_out -= n; ++ z->total_out += n; ++ ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(s->check, q, n); ++ ++ /* copy */ ++ zmemcpy(p, q, n); ++ p += n; ++ q += n; ++ } ++ ++ /* update pointers */ ++ z->next_out = p; ++ s->read = q; ++ ++ /* done */ ++ return r; ++} ++ ++ ++/*+++++*/ ++/* inffast.c -- process literals and length/distance pairs fast ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define base more.Base ++#define next more.Next ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++/* macros for bit input with no checking and for returning unused bytes */ ++#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} ++#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} ++ ++/* Called with number of bytes left to write in window at least 258 ++ (the maximum string length) and number of input bytes available ++ at least ten. The ten bytes are six bytes for the longest length/ ++ distance pair plus four bytes for overloading the bit buffer. */ ++ ++local int inflate_fast(bl, bd, tl, td, s, z) ++uInt bl, bd; ++inflate_huft *tl, *td; ++inflate_blocks_statef *s; ++z_stream *z; ++{ ++ inflate_huft *t; /* temporary pointer */ ++ uInt e; /* extra bits or operation */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ uInt ml; /* mask for literal/length tree */ ++ uInt md; /* mask for distance tree */ ++ uInt c; /* bytes to copy */ ++ uInt d; /* distance back to copy from */ ++ Bytef *r; /* copy source pointer */ ++ ++ /* load input, output, bit values */ ++ LOAD ++ ++ /* initialize masks */ ++ ml = inflate_mask[bl]; ++ md = inflate_mask[bd]; ++ ++ /* do until not enough input or output space for fast loop */ ++ do { /* assume called with m >= 258 && n >= 10 */ ++ /* get literal/length code */ ++ GRABBITS(20) /* max bits for literal/length code */ ++ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) ++ { ++ DUMPBITS(t->bits) ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: * literal '%c'\n" : ++ "inflate: * literal 0x%02x\n", t->base)); ++ *q++ = (Byte)t->base; ++ m--; ++ continue; ++ } ++ do { ++ DUMPBITS(t->bits) ++ if (e & 16) ++ { ++ /* get extra bits for length */ ++ e &= 15; ++ c = t->base + ((uInt)b & inflate_mask[e]); ++ DUMPBITS(e) ++ Tracevv((stderr, "inflate: * length %u\n", c)); ++ ++ /* decode distance base of block to copy */ ++ GRABBITS(15); /* max bits for distance code */ ++ e = (t = td + ((uInt)b & md))->exop; ++ do { ++ DUMPBITS(t->bits) ++ if (e & 16) ++ { ++ /* get extra bits to add to distance base */ ++ e &= 15; ++ GRABBITS(e) /* get extra bits (up to 13) */ ++ d = t->base + ((uInt)b & inflate_mask[e]); ++ DUMPBITS(e) ++ Tracevv((stderr, "inflate: * distance %u\n", d)); ++ ++ /* do the copy */ ++ m -= c; ++ if ((uInt)(q - s->window) >= d) /* offset before dest */ ++ { /* just copy */ ++ r = q - d; ++ *q++ = *r++; c--; /* minimum count is three, */ ++ *q++ = *r++; c--; /* so unroll loop a little */ ++ } ++ else /* else offset after destination */ ++ { ++ e = d - (q - s->window); /* bytes from offset to end */ ++ r = s->end - e; /* pointer to offset */ ++ if (c > e) /* if source crosses, */ ++ { ++ c -= e; /* copy to end of window */ ++ do { ++ *q++ = *r++; ++ } while (--e); ++ r = s->window; /* copy rest from start of window */ ++ } ++ } ++ do { /* copy all or what's left */ ++ *q++ = *r++; ++ } while (--c); ++ break; ++ } ++ else if ((e & 64) == 0) ++ e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; ++ else ++ { ++ z->msg = "invalid distance code"; ++ UNGRAB ++ UPDATE ++ return Z_DATA_ERROR; ++ } ++ } while (1); ++ break; ++ } ++ if ((e & 64) == 0) ++ { ++ if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) ++ { ++ DUMPBITS(t->bits) ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: * literal '%c'\n" : ++ "inflate: * literal 0x%02x\n", t->base)); ++ *q++ = (Byte)t->base; ++ m--; ++ break; ++ } ++ } ++ else if (e & 32) ++ { ++ Tracevv((stderr, "inflate: * end of block\n")); ++ UNGRAB ++ UPDATE ++ return Z_STREAM_END; ++ } ++ else ++ { ++ z->msg = "invalid literal/length code"; ++ UNGRAB ++ UPDATE ++ return Z_DATA_ERROR; ++ } ++ } while (1); ++ } while (m >= 258 && n >= 10); ++ ++ /* not enough input or output--restore pointers and return */ ++ UNGRAB ++ UPDATE ++ return Z_OK; ++} ++ ++ ++/*+++++*/ ++/* zutil.c -- target dependent utility functions for the compression library ++ * Copyright (C) 1995 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ ++ ++char *zlib_version = ZLIB_VERSION; ++ ++char *z_errmsg[] = { ++"stream end", /* Z_STREAM_END 1 */ ++"", /* Z_OK 0 */ ++"file error", /* Z_ERRNO (-1) */ ++"stream error", /* Z_STREAM_ERROR (-2) */ ++"data error", /* Z_DATA_ERROR (-3) */ ++"insufficient memory", /* Z_MEM_ERROR (-4) */ ++"buffer error", /* Z_BUF_ERROR (-5) */ ++""}; ++ ++ ++/*+++++*/ ++/* adler32.c -- compute the Adler-32 checksum of a data stream ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ ++ ++#define BASE 65521L /* largest prime smaller than 65536 */ ++#define NMAX 5552 ++/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ ++ ++#define DO1(buf) {s1 += *buf++; s2 += s1;} ++#define DO2(buf) DO1(buf); DO1(buf); ++#define DO4(buf) DO2(buf); DO2(buf); ++#define DO8(buf) DO4(buf); DO4(buf); ++#define DO16(buf) DO8(buf); DO8(buf); ++ ++/* ========================================================================= */ ++uLong adler32(adler, buf, len) ++ uLong adler; ++ Bytef *buf; ++ uInt len; ++{ ++ unsigned long s1 = adler & 0xffff; ++ unsigned long s2 = (adler >> 16) & 0xffff; ++ int k; ++ ++ if (buf == Z_NULL) return 1L; ++ ++ while (len > 0) { ++ k = len < NMAX ? len : NMAX; ++ len -= k; ++ while (k >= 16) { ++ DO16(buf); ++ k -= 16; ++ } ++ if (k != 0) do { ++ DO1(buf); ++ } while (--k); ++ s1 %= BASE; ++ s2 %= BASE; ++ } ++ return (s2 << 16) | s1; ++} +diff -Naru linux/arch/mips/zboot/Makefile linux.spi/arch/mips/zboot/Makefile +--- linux/arch/mips/zboot/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,84 @@ ++# ++# arch/mips/zboot/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++ ++# Adapted for MIPS Pete Popov, Dan Malek ++# ++# Copyright (C) 1994 by Linus Torvalds ++# Adapted for PowerPC by Gary Thomas ++# modified by Cort (cort@cs.nmt.edu) ++# ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++GZIP_FLAGS = -v9f ++ ++CFLAGS += -D__BOOTER__ -I$(TOPDIR)/arch/$(ARCH)/zboot/include ++AFLAGS += -D__BOOTER__ ++ ++BOOT_TARGETS = zImage zImage.initrd zImage.flash zImage.initrd.flash ++ ++lib/zlib.a: ++ $(MAKE) -C lib ++ ++images/vmlinux.gz: $(TOPDIR)/vmlinux ++ $(MAKE) -C images vmlinux.gz ++ ++$(BOOT_TARGETS): lib/zlib.a images/vmlinux.gz ++ifdef CONFIG_MIPS_PB1000 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_PB1500 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_PB1100 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_PB1550 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_DB1000 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_DB1100 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_DB1500 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_BOSPORUS ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_MIRAGE ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_MTX2 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_COGENT_CSB250 ++ $(MAKE) -C csb250 $@ ++endif ++ifdef CONFIG_MIPS_XXS1500 ++BOOT_DIR = xxs1500 ++endif ++ ++# Do the dirs ++clean: ++ $(MAKE) -C common clean ++ $(MAKE) -C images clean ++ $(MAKE) -C pb1xxx clean ++ $(MAKE) -C xxs1500 clean ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/pb1xxx/head.S linux.spi/arch/mips/zboot/pb1xxx/head.S +--- linux/arch/mips/zboot/pb1xxx/head.S 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/pb1xxx/head.S 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,149 @@ ++/* ++ * arch/mips/kernel/head.S ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1994, 1995 Waldorf Electronics ++ * Written by Ralf Baechle and Andreas Busse ++ * Copyright (C) 1995 - 1999 Ralf Baechle ++ * Copyright (C) 1996 Paul M. Antoine ++ * Modified for DECStation and hence R3000 support by Paul M. Antoine ++ * Further modifications by David S. Miller and Harald Koerfgen ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * ++ * Head.S contains the MIPS exception handler and startup code. ++ * ++ ************************************************************************** ++ * 9 Nov, 2000. ++ * Added Cache Error exception handler and SBDDP EJTAG debug exception. ++ * ++ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ ************************************************************************** ++ */ ++#include <linux/config.h> ++#include <linux/threads.h> ++ ++#include <asm/asm.h> ++#include <asm/cacheops.h> ++#include <asm/mipsregs.h> ++#include <asm/offset.h> ++#include <asm/cachectl.h> ++#include <asm/regdef.h> ++ ++#define IndexInvalidate_I 0x00 ++#define IndexWriteBack_D 0x01 ++ ++ .set noreorder ++ .cprestore ++ LEAF(start) ++start: ++ bal locate ++ nop ++locate: ++ subu s8, ra, 8 /* Where we were loaded */ ++ la sp, (.stack + 8192) ++ ++ move s0, a0 /* Save boot rom start args */ ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ la a0, start /* Where we were linked to run */ ++ ++ move a1, s8 ++ la a2, _edata ++ subu t1, a2, a0 ++ srl t1, t1, 2 ++ ++ /* copy text section */ ++ li t0, 0 ++1: lw v0, 0(a1) ++ nop ++ sw v0, 0(a0) ++ xor t0, t0, v0 ++ addu a0, 4 ++ bne a2, a0, 1b ++ addu a1, 4 ++ ++ /* Clear BSS */ ++ la a0, _edata ++ la a2, _end ++2: sw zero, 0(a0) ++ bne a2, a0, 2b ++ addu a0, 4 ++ ++ /* push the D-Cache and invalidate I-Cache */ ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ /* done */ ++ ++ move a0, s8 /* load address */ ++ move a1, t1 /* length in words */ ++ move a2, t0 /* checksum */ ++ move a3, sp ++ ++ la ra, 1f ++ la k0, decompress_kernel ++ jr k0 ++ nop ++1: ++ ++ move a0, s0 ++ move a1, s1 ++ move a2, s2 ++ move a3, s3 ++ li k0, KERNEL_ENTRY ++ jr k0 ++ nop ++3: ++ b 3b ++ END(start) ++ ++ LEAF(udelay) ++udelay: ++ END(udelay) ++ ++ ++ LEAF(FlushCache) ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ jr ra ++ nop ++ END(FlushCache) ++ ++ .comm .stack,4096*2,4 +diff -Naru linux/arch/mips/zboot/pb1xxx/Makefile linux.spi/arch/mips/zboot/pb1xxx/Makefile +--- linux/arch/mips/zboot/pb1xxx/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/pb1xxx/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,135 @@ ++# arch/mips/zboot/pb1xxx/Makefile ++# ++# Makefile for Alchemy Semiconductor Pb1[015]00 boards. ++# All of the boot loader code was derived from the ppc ++# boot code. ++# ++# Copyright 2001,2002 MontaVista Software Inc. ++# ++# Author: Mark A. Greer ++# mgreer@mvista.com ++# Ported and modified for mips support by ++# Pete Popov <ppopov@mvista.com> ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++######################################################################### ++# START BOARD SPECIFIC VARIABLES ++ifdef CONFIG_MIPS_PB1000 ++BNAME=pb1000 ++endif ++ ++ifdef CONFIG_MIPS_PB1100 ++BNAME=pb1100 ++endif ++ ++ifdef CONFIG_MIPS_PB1500 ++BNAME=pb1500 ++endif ++ ++ifdef CONFIG_MIPS_PB1550 ++BNAME=pb1550 ++endif ++ ++ifdef CONFIG_MIPS_DB1000 ++BNAME=db1000 ++endif ++ ++ifdef CONFIG_MIPS_DB1100 ++BNAME=db1100 ++endif ++ ++ifdef CONFIG_MIPS_DB1500 ++BNAME=db1500 ++endif ++ ++ifdef CONFIG_MIPS_BOSPORUS ++BNAME=bosporus ++endif ++ ++ifdef CONFIG_MIPS_MIRAGE ++BNAME=mirage ++endif ++ ++ifdef CONFIG_MIPS_MTX2 ++BNAME=mtx-2 ++endif ++ ++# These two variables control where the zImage is stored ++# in flash and loaded in memory. It only controls how the srec ++# file is generated, the code is the same. ++RAM_RUN_ADDR = 0x81000000 ++FLASH_LOAD_ADDR = 0xBFD00000 ++ ++# These two variables specify the free ram region ++# that can be used for temporary malloc area ++AVAIL_RAM_START=0x80400000 ++AVAIL_RAM_END=0x80800000 ++ ++# This one must match the LOADADDR in arch/mips/Makefile! ++LOADADDR=0x80100000 ++# END BOARD SPECIFIC VARIABLES ++######################################################################### ++ ++OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ ++ ../common/au1k_uart.o ../common/string.o ../common/ctype.o ++LIBS := ../lib/zlib.a ++ ++ENTRY := ../utils/entry ++OFFSET := ../utils/offset ++SIZE := ../utils/size ++ ++LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic ++OBJCOPY_ARGS = -O elf32-tradlittlemips ++ ++all: zImage ++ ++clean: ++ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec ++ ++head.o: head.S $(TOPDIR)/vmlinux ++ $(CC) $(AFLAGS) \ ++ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \ ++ -c -o $*.o $< ++ ++../common/misc-simple.o: ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -DZIMAGE_SIZE=0 -c -o $@ $*.c ++ ++zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o ++ $(OBJCOPY) \ ++ --add-section=.image=../images/vmlinux.gz \ ++ --set-section-flags=.image=contents,alloc,load,readonly,data \ ++ ../common/dummy.o image.o ++ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \ ++ -R .initrd -R .sysmap ++ ++# Here we manipulate the image in order to get it the necessary ++# srecord file we need. ++zImage: zvmlinux ++ mv zvmlinux ../images/zImage.$(BNAME) ++ $(OBJCOPY) -O srec ../images/zImage.$(BNAME) ../images/$(BNAME).srec ++ ++zImage.flash: zImage ++ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \ ++ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/utils/entry linux.spi/arch/mips/zboot/utils/entry +--- linux/arch/mips/zboot/utils/entry 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/utils/entry 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,12 @@ ++#!/bin/sh ++ ++# grab the kernel_entry address from the vmlinux elf image ++entry=`$1 $2 | grep kernel_entry` ++ ++fs=`echo $entry | grep ffffffff` # check toolchain output ++ ++if [ -n "$fs" ]; then ++ echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'` ++else ++ echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'` ++fi +diff -Naru linux/arch/mips/zboot/utils/offset linux.spi/arch/mips/zboot/utils/offset +--- linux/arch/mips/zboot/utils/offset 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/utils/offset 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,3 @@ ++#!/bin/sh ++ ++echo "0x"`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` +diff -Naru linux/arch/mips/zboot/utils/size linux.spi/arch/mips/zboot/utils/size +--- linux/arch/mips/zboot/utils/size 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/utils/size 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,4 @@ ++#!/bin/sh ++ ++OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` ++echo "0x"$OFFSET +diff -Naru linux/arch/mips/zboot/xxs1500/head.S linux.spi/arch/mips/zboot/xxs1500/head.S +--- linux/arch/mips/zboot/xxs1500/head.S 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/xxs1500/head.S 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,137 @@ ++/* ++ * arch/mips/kernel/head.S ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1994, 1995 Waldorf Electronics ++ * Written by Ralf Baechle and Andreas Busse ++ * Copyright (C) 1995 - 1999 Ralf Baechle ++ * Copyright (C) 1996 Paul M. Antoine ++ * Modified for DECStation and hence R3000 support by Paul M. Antoine ++ * Further modifications by David S. Miller and Harald Koerfgen ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * ++ * Head.S contains the MIPS exception handler and startup code. ++ * ++ ************************************************************************** ++ * 9 Nov, 2000. ++ * Added Cache Error exception handler and SBDDP EJTAG debug exception. ++ * ++ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ ************************************************************************** ++ */ ++#include <linux/config.h> ++#include <linux/threads.h> ++ ++#include <asm/asm.h> ++#include <asm/cacheops.h> ++#include <asm/mipsregs.h> ++#include <asm/offset.h> ++#include <asm/cachectl.h> ++#include <asm/regdef.h> ++ ++#define IndexInvalidate_I 0x00 ++ ++ .set noreorder ++ .cprestore ++ LEAF(start) ++start: ++ ++locate: ++ la sp, .stack ++ move s0, a0 ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ la a0, start ++ ++ li a1, FLASH_LOAD_ADDR ++ la a2, _edata ++ subu t1, a2, a0 ++ srl t1, t1, 2 ++ ++ /* copy text section */ ++ li t0, 0 ++1: lw v0, 0(a1) ++ nop ++ sw v0, 0(a0) ++ xor t0, t0, v0 ++ addu a0, 4 ++ bne a2, a0, 1b ++ addu a1, 4 ++ ++ /* Clear BSS */ ++ la a0, _edata ++ la a2, _end ++2: sw zero, 0(a0) ++ bne a2, a0, 2b ++ addu a0, 4 ++ ++ /* flush the I-Cache */ ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ /* done */ ++ ++ li a0, FLASH_LOAD_ADDR /* load address */ ++ move a1, t1 /* length in words */ ++ move a2, t0 /* checksum */ ++ move a3, sp ++ ++ la ra, 1f ++ la k0, decompress_kernel ++ jr k0 ++ nop ++1: ++ ++ move a0, s0 ++ move a1, s1 ++ move a2, s2 ++ move a3, s3 ++ li k0, KERNEL_ENTRY ++ jr k0 ++ nop ++3: ++ b 3b ++ END(start) ++ ++ LEAF(udelay) ++udelay: ++ END(udelay) ++ ++ ++ LEAF(FlushCache) ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ jr ra ++ nop ++ END(FlushCache) ++ ++ .comm .stack,4096*2,4 +diff -Naru linux/arch/mips/zboot/xxs1500/ld.script linux.spi/arch/mips/zboot/xxs1500/ld.script +--- linux/arch/mips/zboot/xxs1500/ld.script 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/xxs1500/ld.script 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,147 @@ ++OUTPUT_ARCH(mips) ++ENTRY(start) ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ /* . = 0x81000000; */ ++ .init : { *(.init) } =0 ++ .text : ++ { ++ _ftext = . ; ++ *(.text) ++ *(.rodata) ++ *(.rodata1) ++ /* .gnu.warning sections are handled specially by elf32.em. */ ++ *(.gnu.warning) ++ } =0 ++ .kstrtab : { *(.kstrtab) } ++ ++ . = ALIGN(16); /* Exception table */ ++ __start___ex_table = .; ++ __ex_table : { *(__ex_table) } ++ __stop___ex_table = .; ++ ++ __start___dbe_table = .; /* Exception table for data bus errors */ ++ __dbe_table : { *(__dbe_table) } ++ __stop___dbe_table = .; ++ ++ __start___ksymtab = .; /* Kernel symbol table */ ++ __ksymtab : { *(__ksymtab) } ++ __stop___ksymtab = .; ++ ++ _etext = .; ++ ++ . = ALIGN(8192); ++ .data.init_task : { *(.data.init_task) } ++ ++ /* Startup code */ ++ . = ALIGN(4096); ++ __init_begin = .; ++ .text.init : { *(.text.init) } ++ .data.init : { *(.data.init) } ++ . = ALIGN(16); ++ __setup_start = .; ++ .setup.init : { *(.setup.init) } ++ __setup_end = .; ++ __initcall_start = .; ++ .initcall.init : { *(.initcall.init) } ++ __initcall_end = .; ++ . = ALIGN(4096); /* Align double page for init_task_union */ ++ __init_end = .; ++ ++ . = ALIGN(4096); ++ .data.page_aligned : { *(.data.idt) } ++ ++ . = ALIGN(32); ++ .data.cacheline_aligned : { *(.data.cacheline_aligned) } ++ ++ .fini : { *(.fini) } =0 ++ .reginfo : { *(.reginfo) } ++ /* Adjust the address for the data segment. We want to adjust up to ++ the same address within the page on the next page up. It would ++ be more correct to do this: ++ . = .; ++ The current expression does not correctly handle the case of a ++ text segment ending precisely at the end of a page; it causes the ++ data segment to skip a page. The above expression does not have ++ this problem, but it will currently (2/95) cause BFD to allocate ++ a single segment, combining both text and data, for this case. ++ This will prevent the text segment from being shared among ++ multiple executions of the program; I think that is more ++ important than losing a page of the virtual address space (note ++ that no actual memory is lost; the page which is skipped can not ++ be referenced). */ ++ . = .; ++ .data : ++ { ++ _fdata = . ; ++ *(.data) ++ ++ /* Align the initial ramdisk image (INITRD) on page boundaries. */ ++ . = ALIGN(4096); ++ __rd_start = .; ++ *(.initrd) ++ __rd_end = .; ++ . = ALIGN(4096); ++ ++ CONSTRUCTORS ++ } ++ .data1 : { *(.data1) } ++ _gp = . + 0x8000; ++ .lit8 : { *(.lit8) } ++ .lit4 : { *(.lit4) } ++ .ctors : { *(.ctors) } ++ .dtors : { *(.dtors) } ++ .got : { *(.got.plt) *(.got) } ++ .dynamic : { *(.dynamic) } ++ /* We want the small data sections together, so single-instruction offsets ++ can access them all, and initialized data all before uninitialized, so ++ we can shorten the on-disk segment size. */ ++ .sdata : { *(.sdata) } ++ . = ALIGN(4); ++ _edata = .; ++ PROVIDE (edata = .); ++ ++ __bss_start = .; ++ _fbss = .; ++ .sbss : { *(.sbss) *(.scommon) } ++ .bss : ++ { ++ *(.dynbss) ++ *(.bss) ++ *(COMMON) ++ . = ALIGN(4); ++ _end = . ; ++ PROVIDE (end = .); ++ } ++ ++ /* Sections to be discarded */ ++ /DISCARD/ : ++ { ++ *(.text.exit) ++ *(.data.exit) ++ *(.exitcall.exit) ++ } ++ ++ /* This is the MIPS specific mdebug section. */ ++ .mdebug : { *(.mdebug) } ++ /* These are needed for ELF backends which have not yet been ++ converted to the new style linker. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ /* DWARF debug sections. ++ Symbols in the .debug DWARF section are relative to the beginning of the ++ section so we begin .debug at 0. It's not clear yet what needs to happen ++ for the others. */ ++ .debug 0 : { *(.debug) } ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ .line 0 : { *(.line) } ++ /* These must appear regardless of . */ ++ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } ++ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } ++ .comment : { *(.comment) } ++ .note : { *(.note) } ++} +diff -Naru linux/arch/mips/zboot/xxs1500/Makefile linux.spi/arch/mips/zboot/xxs1500/Makefile +--- linux/arch/mips/zboot/xxs1500/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/xxs1500/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,123 @@ ++# arch/mips/compressed/alchemy/Makefile ++# ++# Makefile for Alchemy Semiconductor Pb1[015]00 boards. ++# All of the boot loader code was derived from the ppc ++# boot code. ++# ++# Copyright 2001,2002 MontaVista Software Inc. ++# ++# Author: Mark A. Greer ++# mgreer@mvista.com ++# Ported and modified for mips support by ++# Pete Popov <ppopov@mvista.com> ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++######################################################################### ++# START BOARD SPECIFIC VARIABLES ++BNAME=xxs1500 ++ ++ ++# These two variables control where the zImage is stored ++# in flash and loaded in memory. If you change either one, ++# be sure to make the appropriate change to the zImage ++# rule. ++RAM_LOAD_ADDR = 0x81000000 ++FLASH_LOAD_ADDR = 0xBF000000 ++ ++# These two variables specify the free ram region ++# that can be used for temporary malloc area ++AVAIL_RAM_START=0x80400000 ++AVAIL_RAM_END=0x80800000 ++ ++# This one must match the LOADADDR in arch/mips/Makefile! ++LOADADDR=0x80100000 ++# END BOARD SPECIFIC VARIABLES ++######################################################################### ++ ++ZLINKFLAGS = -T ld.script -Ttext $(RAM_LOAD_ADDR) ++ ++OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ ++ ../common/au1k_uart.o ../common/string.o ../common/ctype.o ++LIBS := ../lib/zlib.a ++ ++ENTRY := ../utils/entry ++OFFSET := ../utils/offset ++SIZE := ../utils/size ++ ++all: zImage ++ ++clean: ++ rm -rf *.o vmlinux* zvmlinux.* ++ ++head.o: head.S $(TOPDIR)/vmlinux ++ $(CC) -DFLASH_LOAD_ADDR=$(FLASH_LOAD_ADDR) $(AFLAGS) \ ++ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \ ++ -c -o $*.o $< ++ ++../common/misc-simple.o: ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -DZIMAGE_SIZE=0 -c -o $@ $*.c ++ ++# This is the first pass at building the boot loader image, ++# without knowing the file offset where the vmlinuz.gz ++# kernel will end up. We build this image, check the offset, ++# and then rebuild it with the correct offset and size ++# passed to mips-simple.c ++zvmlinux.no: $(OBJECTS) $(LIBS) ../images/vmlinux.gz ++ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) ++ $(OBJCOPY) -R .comment \ ++ --add-section=image=../images/vmlinux.gz \ ++ $@.tmp $@ ++ # rm -f $@.tmp ++ ++ ++# This is the final image we build, now that we know what ++# the vmlinuz.gz offset is. ++zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz zvmlinux.no ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ ++ -DZIMAGE_OFFSET=$(shell sh $(OFFSET) $(OBJDUMP) $@.no image) \ ++ -DZIMAGE_SIZE=$(shell sh $(SIZE) $(OBJDUMP) $@.no image) \ ++ -D__BOOTER__ \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -c -o ../common/misc-simple.o ../common/misc-simple.c ++ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) ++ $(OBJCOPY) -R .comment \ ++ --add-section=image=../images/vmlinux.gz \ ++ $@.tmp $@ ++ $(OBJCOPY) --adjust-section-vma=image+$(RAM_LOAD_ADDR) $@ ++ $(OBJCOPY) --adjust-section-vma=image+$(shell sh $(OFFSET) \ ++ $(OBJDUMP) $@.no image ) $@ ++ # rm -f $@.tmp ++ # rm -f $@.no ++ ++ ++# Here we manipulate the image in order to get it the necessary ++# srecord file we need. ++zImage: zvmlinux ++ mv zvmlinux ../images/$@.$(BNAME) ++ $(OBJCOPY) --set-section-flags=image=alloc,load,code ../images/$@.$(BNAME) ++ $(OBJCOPY) -O srec --adjust-vma 0x3e000000 \ ++ ../images/$@.$(BNAME) ../images/$@.$(BNAME).srec ++ # rm ../images/vmlinux.gz ++ ++include $(TOPDIR)/Rules.make |