[Debootloaders-devel] r157 - in trunk/miboot: . src

Aurélien GÉRÔME ag-guest at costa.debian.org
Sun Aug 6 10:53:18 UTC 2006


Author: ag-guest
Date: 2006-08-06 10:53:03 +0000 (Sun, 06 Aug 2006)
New Revision: 157

Added:
   trunk/miboot/BSTP.ppc.ld
   trunk/miboot/Makefile
   trunk/miboot/boot.m68k.ld
   trunk/miboot/src/
   trunk/miboot/src/EnterPPCSupervisor.S
   trunk/miboot/src/EnterPPCSupervisor.h
   trunk/miboot/src/LowLevelBoot.c
   trunk/miboot/src/LowLevelBoot.h
   trunk/miboot/src/bootstrap.S
   trunk/miboot/src/bootx.h
   trunk/miboot/src/debug_sprintf.c
   trunk/miboot/src/debug_text.c
   trunk/miboot/src/debug_text.h
   trunk/miboot/src/elf_loader_defs.h
   trunk/miboot/src/extract_dev_tree.c
   trunk/miboot/src/extract_dev_tree.h
   trunk/miboot/src/linux_type_defs.h
   trunk/miboot/src/miBoot_boot2.S
   trunk/miboot/src/miBoot_boot3.c
   trunk/miboot/src/miBoot_boot4.c
   trunk/miboot/src/nr_wrapper.c
   trunk/miboot/src/nr_wrapper.h
   trunk/miboot/src/pre_strap_ppc.c
   trunk/miboot/src/pre_strap_ppc.exp
   trunk/miboot/src/processor.h
   trunk/miboot/src/rs6000.h
   trunk/miboot/src/test_paint.c
   trunk/miboot/src/uLibc.c
   trunk/miboot/src/uLibc.h
   trunk/miboot/src/zlib.c
   trunk/miboot/src/zlib.h
Log:
Import source code of miBoot-1.0d4 port to GNU toolchain.


Added: trunk/miboot/BSTP.ppc.ld
===================================================================
--- trunk/miboot/BSTP.ppc.ld	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/BSTP.ppc.ld	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,30 @@
+ENTRY (__start)
+SECTIONS {
+    . = 0x0;
+    .text : {
+        *(.text)
+        *(.pr)
+        *(.ro)
+        *(.gl)
+    }
+    . = ALIGN (0x1000);
+    .data : {
+        *(.tc0)
+        *(.tc)
+        *(.td)
+        *(.data)
+        *(.rw)
+        *(.ua)
+        *(.ds)
+        *(.bss)
+        *(.bs)
+        *(COMMON)
+    }
+    . = ALIGN (0x1000);
+    .loader : {
+        *(.loader)
+    }
+    .debug : {
+        *(.debug)
+    }
+}

Added: trunk/miboot/Makefile
===================================================================
--- trunk/miboot/Makefile	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/Makefile	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,154 @@
+M68K_CC = m68k-elf-gcc
+M68K_CFLAGS = \
+    -Dmacintosh \
+    -I../libmacos -I../universal-interfaces/CIncludes \
+    -m68020 -mpcrel \
+    -fcall-used-a0 -fcall-used-a1 -fcall-used-a2 \
+    -fcall-used-d0 -fcall-used-d1 -fcall-used-d2 \
+    -ffixed-a5 \
+    -O1 \
+    -Wall -Wno-multichar
+M68K_LD = m68k-elf-ld
+M68K_LDFLAGS =
+
+PPC_CC = powerpc-ibm-aix4.1-gcc
+PPC_CFLAGS = \
+    -Dmacintosh \
+    -I../libmacos -I../universal-interfaces/CIncludes \
+    -mpowerpc \
+    -O1 \
+    -Wall -Wno-multichar
+PPC_LD = powerpc-ibm-aix4.1-ld
+PPC_LDFLAGS = -shared -call_shared
+PPC_XCOFF2PEF = ../xcoff2pef/xcoff2pef
+
+
+SYSTEM_HQX = System.hqx
+SYSTEM_RSRC = System.rsrc
+
+FINDER_HQX = Finder.hqx
+
+BOOT1_BIN = ../hfs-bootblock/boot-1.m68k.bin
+
+BOOT2_BIN = src/boot-2.m68k.bin
+BOOT2_OBJS = \
+    src/miBoot_boot2.m68k.o
+BOOT2_LIBS =
+
+BOOT3_BIN = src/boot-3.m68k.bin
+BOOT3_OBJS = \
+    src/miBoot_boot3.m68k.o \
+    src/debug_text.m68k.o \
+    src/debug_sprintf.m68k.o
+BOOT3_LIBS =
+
+BOOT4_BIN = src/boot-4.m68k.bin
+BOOT4_OBJS = \
+    src/miBoot_boot4.m68k.o \
+    src/nr_wrapper.m68k.o \
+    src/extract_dev_tree.m68k.o \
+    src/LowLevelBoot.m68k.o \
+    src/EnterPPCSupervisor.m68k.o \
+    src/zlib.m68k.o \
+    src/debug_text.m68k.o \
+    src/debug_sprintf.m68k.o \
+    src/uLibc.m68k.o
+BOOT4_LIBS = \
+    -L../libmacos -lmacos.m68k
+
+BSTP128_PEF = src/BSTP-128.ppc.pef
+BSTP128_XCOFF = src/BSTP-128.ppc.xcoff
+BSTP128_OBJS = \
+    src/bootstrap.ppc.o
+BSTP128_LIBS =
+
+BSTP129_PEF = src/BSTP-129.ppc.pef
+BSTP129_XCOFF = src/BSTP-129.ppc.xcoff
+BSTP129_OBJS = \
+    src/pre_strap_ppc.ppc.o \
+    src/debug_text.ppc.o \
+    src/debug_sprintf.ppc.o
+BSTP129_LIBS = \
+    ../libmacos/DriverServicesLib.exp \
+    ../libmacos/NameRegistryLib.exp \
+    ../libmacos/PCILib.exp
+
+
+all: ${SYSTEM_HQX} ${FINDER_HQX}
+
+
+${SYSTEM_HQX}: ${SYSTEM_RSRC}
+	binhex -r -t zsys -c MACS $< | \
+	    sed "1 s%; you knew that already.% with BinHex 4.0%" > $@
+
+${FINDER_HQX}:
+	binhex -r -t FNDR -c zsys /dev/null | \
+	    sed "1 s%; you knew that already.% with BinHex 4.0%" > $@
+
+
+${SYSTEM_RSRC}: \
+    System.rsrce \
+    ${BOOT2_BIN} \
+    ${BOOT3_BIN} \
+    ${BOOT4_BIN} \
+    ${BSTP128_PEF} \
+    ${BSTP129_PEF}
+	sed "s%@System_rsrc@%${SYSTEM_RSRC}%g" < System.rsrce | \
+	    sed "s%@boot-1_bin@%${BOOT1_BIN}%g" | \
+	    sed "s%@boot-2_bin@%${BOOT2_BIN}%g" | \
+	    sed "s%@boot-3_bin@%${BOOT3_BIN}%g" | \
+	    sed "s%@boot-4_bin@%${BOOT4_BIN}%g" | \
+	    sed "s%@BSTP-128_bin@%${BSTP128_PEF}%g" | \
+	    sed "s%@BSTP-129_bin@%${BSTP129_PEF}%g" | \
+	    rsrce
+
+
+${BOOT2_BIN}: ${BOOT2_OBJS}
+	${M68K_LD} ${M68K_LDFLAGS} \
+	    --oformat=binary --script=boot.m68k.ld -o $@ $+ ${BOOT2_LIBS}
+
+${BOOT3_BIN}: ${BOOT3_OBJS}
+	${M68K_LD} ${M68K_LDFLAGS} \
+	    --oformat=binary --script=boot.m68k.ld -o $@ $+ ${BOOT3_LIBS}
+
+${BOOT4_BIN}: ${BOOT4_OBJS}
+	${M68K_LD} ${M68K_LDFLAGS} \
+	    --oformat=binary --script=boot.m68k.ld -o $@ $+ ${BOOT4_LIBS}
+
+${BSTP128_PEF}: ${BSTP128_XCOFF}
+	${PPC_XCOFF2PEF} -o $@ $<
+
+${BSTP129_PEF}: ${BSTP129_XCOFF}
+	${PPC_XCOFF2PEF} --routine_descriptor -o $@ $<
+
+${BSTP128_XCOFF}: ${BSTP128_OBJS}
+	${PPC_LD} ${PPC_LDFLAGS} --script=BSTP.ppc.ld -o $@ $+ ${BSTP128_LIBS}
+
+${BSTP129_XCOFF}: ${BSTP129_OBJS}
+	${PPC_LD} ${PPC_LDFLAGS} --script=BSTP.ppc.ld -o $@ $+ ${BSTP129_LIBS}
+
+
+%.m68k.o: %.c
+	${M68K_CC} -c ${M68K_CFLAGS} -o $@ $<
+
+%.m68k.o: %.S
+	${M68K_CC} -c ${M68K_CFLAGS} -o $@ $<
+
+%.ppc.o: %.c
+	${PPC_CC} -c ${PPC_CFLAGS} -o $@ $<
+
+%.ppc.o: %.S
+	${PPC_CC} -c ${PPC_CFLAGS} -o $@ $<
+
+
+test.hfs: ${BOOT1_BIN} ${SYSTEM_HQX} ${FINDER_HQX}
+	dd if=/dev/zero of=$@ bs=1b count=2880
+	hformat -l "test" $@
+	dd if=${BOOT1_BIN} of=$@ conv=notrunc
+	hmount $@
+	hmkdir "test:miboot"
+	hcopy -b ${SYSTEM_HQX} "test:miboot:System"
+	hcopy -b ${FINDER_HQX} "test:miboot:Finder"
+	hcopy -r ../zImage "test:zImage"
+	hattrib -b "test:miboot"
+	humount

Added: trunk/miboot/boot.m68k.ld
===================================================================
--- trunk/miboot/boot.m68k.ld	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/boot.m68k.ld	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,9 @@
+SECTIONS {
+    .boot : {
+        *(.text*)
+        *(.rodata*)
+        *(.data*)
+        *(.bss*)
+        *(COMMON)
+    }
+}

Added: trunk/miboot/src/EnterPPCSupervisor.S
===================================================================
--- trunk/miboot/src/EnterPPCSupervisor.S	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/EnterPPCSupervisor.S	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,148 @@
+#define PPCRegisterList_PC(base) \
+    0(base)
+
+#define PPCRegisterList_GPR(base,ix) \
+    4+ix*4(base)
+
+#define PPCRegisterList_FPR(base,ix,offset) \
+    132+ix*8+offset(base)
+
+// Implementation
+/*
+ * void EnterPPCSupervisor(PPCRegisterList* regList);
+ */
+	.text
+	.align 2
+	.globl EnterPPCSupervisor
+EnterPPCSupervisor:
+	// Load the address of the register list into %a3
+	move.l	0x0004(%sp),%a3
+	
+	// Disable 68K interrupts
+	ori.w	#0x0700,%sr
+	
+	// Mess with the stack!
+	move.l	%sp,%d0
+	andi.l	#0xFFFFFC00,%d0
+	move.l	%d0,%sp
+	move.l	#0x00BF,%d0
+loop:
+	clr.l		-(%sp)
+	dbra		%d0,loop
+	
+	// Set up the program counter
+	move.l	PPCRegisterList_PC(%a3),0x00FC(%sp)				// PC
+	
+	// Set up the general-purpose registers
+	move.l	PPCRegisterList_GPR(%a3,0),0x0100+0*8+4(%sp)	// R0
+	move.l	PPCRegisterList_GPR(%a3,1),0x0100+1*8+4(%sp)	// R1
+	move.l	PPCRegisterList_GPR(%a3,2),0x0100+2*8+4(%sp)	// R2
+	move.l	PPCRegisterList_GPR(%a3,3),0x0100+3*8+4(%sp)	// R3
+	move.l	PPCRegisterList_GPR(%a3,4),0x0100+4*8+4(%sp)	// R4
+	move.l	PPCRegisterList_GPR(%a3,5),0x0100+5*8+4(%sp)	// R5
+	move.l	PPCRegisterList_GPR(%a3,6),0x0100+6*8+4(%sp)	// R6
+	move.l	PPCRegisterList_GPR(%a3,7),0x0100+7*8+4(%sp)	// R7
+	move.l	PPCRegisterList_GPR(%a3,8),0x0100+8*8+4(%sp)	// R8
+	move.l	PPCRegisterList_GPR(%a3,9),0x0100+9*8+4(%sp)	// R9
+	move.l	PPCRegisterList_GPR(%a3,10),0x0100+10*8+4(%sp)	// R10
+	move.l	PPCRegisterList_GPR(%a3,11),0x0100+11*8+4(%sp)	// R11
+	move.l	PPCRegisterList_GPR(%a3,12),0x0100+12*8+4(%sp)	// R12
+	move.l	PPCRegisterList_GPR(%a3,13),0x0100+13*8+4(%sp)	// R13
+	move.l	PPCRegisterList_GPR(%a3,14),0x0100+14*8+4(%sp)	// R14
+	move.l	PPCRegisterList_GPR(%a3,15),0x0100+15*8+4(%sp)	// R15
+	move.l	PPCRegisterList_GPR(%a3,16),0x0100+16*8+4(%sp)	// R16
+	move.l	PPCRegisterList_GPR(%a3,17),0x0100+17*8+4(%sp)	// R17
+	move.l	PPCRegisterList_GPR(%a3,18),0x0100+18*8+4(%sp)	// R18
+	move.l	PPCRegisterList_GPR(%a3,19),0x0100+19*8+4(%sp)	// R19
+	move.l	PPCRegisterList_GPR(%a3,20),0x0100+20*8+4(%sp)	// R20
+	move.l	PPCRegisterList_GPR(%a3,21),0x0100+21*8+4(%sp)	// R21
+	move.l	PPCRegisterList_GPR(%a3,22),0x0100+22*8+4(%sp)	// R22
+	move.l	PPCRegisterList_GPR(%a3,23),0x0100+23*8+4(%sp)	// R23
+	move.l	PPCRegisterList_GPR(%a3,24),0x0100+24*8+4(%sp)	// R24
+	move.l	PPCRegisterList_GPR(%a3,25),0x0100+25*8+4(%sp)	// R25
+	move.l	PPCRegisterList_GPR(%a3,26),0x0100+26*8+4(%sp)	// R26
+	move.l	PPCRegisterList_GPR(%a3,27),0x0100+27*8+4(%sp)	// R27
+	move.l	PPCRegisterList_GPR(%a3,28),0x0100+28*8+4(%sp)	// R28
+	move.l	PPCRegisterList_GPR(%a3,29),0x0100+29*8+4(%sp)	// R29
+	move.l	PPCRegisterList_GPR(%a3,30),0x0100+30*8+4(%sp)	// R30
+	move.l	PPCRegisterList_GPR(%a3,31),0x0100+31*8+4(%sp)	// R31
+	
+	// Set up the floating-point registers
+	move.l	PPCRegisterList_FPR(%a3,0,0),0x0200+0*8+0(%sp)	// FPR0
+	move.l	PPCRegisterList_FPR(%a3,0,4),0x0200+0*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,1,0),0x0200+1*8+0(%sp)	// FPR1
+	move.l	PPCRegisterList_FPR(%a3,1,4),0x0200+1*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,2,0),0x0200+2*8+0(%sp)	// FPR2
+	move.l	PPCRegisterList_FPR(%a3,2,4),0x0200+2*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,3,0),0x0200+3*8+0(%sp)	// FPR3
+	move.l	PPCRegisterList_FPR(%a3,3,4),0x0200+3*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,4,0),0x0200+4*8+0(%sp)	// FPR4
+	move.l	PPCRegisterList_FPR(%a3,4,4),0x0200+4*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,5,0),0x0200+5*8+0(%sp)	// FPR5
+	move.l	PPCRegisterList_FPR(%a3,5,4),0x0200+5*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,6,0),0x0200+6*8+0(%sp)	// FPR6
+	move.l	PPCRegisterList_FPR(%a3,6,4),0x0200+6*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,7,0),0x0200+7*8+0(%sp)	// FPR7
+	move.l	PPCRegisterList_FPR(%a3,7,4),0x0200+7*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,8,0),0x0200+8*8+0(%sp)	// FPR8
+	move.l	PPCRegisterList_FPR(%a3,8,4),0x0200+8*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,9,0),0x0200+9*8+0(%sp)	// FPR9
+	move.l	PPCRegisterList_FPR(%a3,9,4),0x0200+9*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,10,0),0x0200+10*8+0(%sp)	// FPR10
+	move.l	PPCRegisterList_FPR(%a3,10,4),0x0200+10*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,11,0),0x0200+11*8+0(%sp)	// FPR11
+	move.l	PPCRegisterList_FPR(%a3,11,4),0x0200+11*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,12,0),0x0200+12*8+0(%sp)	// FPR12
+	move.l	PPCRegisterList_FPR(%a3,12,4),0x0200+12*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,13,0),0x0200+13*8+0(%sp)	// FPR13
+	move.l	PPCRegisterList_FPR(%a3,13,4),0x0200+13*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,14,0),0x0200+14*8+0(%sp)	// FPR14
+	move.l	PPCRegisterList_FPR(%a3,14,4),0x0200+14*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,15,0),0x0200+15*8+0(%sp)	// FPR15
+	move.l	PPCRegisterList_FPR(%a3,15,4),0x0200+15*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,16,0),0x0200+16*8+0(%sp)	// FPR16
+	move.l	PPCRegisterList_FPR(%a3,16,4),0x0200+16*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,17,0),0x0200+17*8+0(%sp)	// FPR17
+	move.l	PPCRegisterList_FPR(%a3,17,4),0x0200+17*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,18,0),0x0200+18*8+0(%sp)	// FPR18
+	move.l	PPCRegisterList_FPR(%a3,18,4),0x0200+18*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,19,0),0x0200+19*8+0(%sp)	// FPR19
+	move.l	PPCRegisterList_FPR(%a3,19,4),0x0200+19*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,20,0),0x0200+20*8+0(%sp)	// FPR20
+	move.l	PPCRegisterList_FPR(%a3,20,4),0x0200+20*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,21,0),0x0200+21*8+0(%sp)	// FPR21
+	move.l	PPCRegisterList_FPR(%a3,21,4),0x0200+21*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,22,0),0x0200+22*8+0(%sp)	// FPR22
+	move.l	PPCRegisterList_FPR(%a3,22,4),0x0200+22*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,23,0),0x0200+23*8+0(%sp)	// FPR23
+	move.l	PPCRegisterList_FPR(%a3,23,4),0x0200+23*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,24,0),0x0200+24*8+0(%sp)	// FPR24
+	move.l	PPCRegisterList_FPR(%a3,24,4),0x0200+24*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,25,0),0x0200+25*8+0(%sp)	// FPR25
+	move.l	PPCRegisterList_FPR(%a3,25,4),0x0200+25*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,26,0),0x0200+26*8+0(%sp)	// FPR26
+	move.l	PPCRegisterList_FPR(%a3,26,4),0x0200+26*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,27,0),0x0200+27*8+0(%sp)	// FPR27
+	move.l	PPCRegisterList_FPR(%a3,27,4),0x0200+27*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,28,0),0x0200+28*8+0(%sp)	// FPR28
+	move.l	PPCRegisterList_FPR(%a3,28,4),0x0200+28*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,29,0),0x0200+29*8+0(%sp)	// FPR29
+	move.l	PPCRegisterList_FPR(%a3,29,4),0x0200+29*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,30,0),0x0200+30*8+0(%sp)	// FPR30
+	move.l	PPCRegisterList_FPR(%a3,30,4),0x0200+30*8+4(%sp)
+	move.l	PPCRegisterList_FPR(%a3,31,0),0x0200+31*8+0(%sp)	// FPR31
+	move.l	PPCRegisterList_FPR(%a3,31,4),0x0200+31*8+4(%sp)
+	
+	// This causes the 68K emulator to put us in priviledged mode and execute our routine.
+	move.l	#0x47617279 /* 'Gary' */,%a0
+	move.l	#0x05051956,%a1
+	move.l	#0x0000C000,%d0
+	moveq	#0,%d2
+	reset
+	
+	move.l	%sp,-(%sp)
+wait:
+	.word	0xFE03
+	beq		wait
+	
+	rts

Added: trunk/miboot/src/EnterPPCSupervisor.h
===================================================================
--- trunk/miboot/src/EnterPPCSupervisor.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/EnterPPCSupervisor.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,38 @@
+#ifndef __ENTER_PPC_SUPERVISOR_H__
+#define __ENTER_PPC_SUPERVISOR_H__
+
+#include <MacTypes.h>
+#include <MixedMode.h>
+
+#if TARGET_CPU_68K
+typedef unsigned long float_reg_t[2];
+#elif TARGET_CPU_PPC
+typedef double float_reg_t;
+#else
+#error Unsupported CPU !
+#endif
+
+typedef struct PPCRegisterList
+{
+	unsigned long	PC;
+	unsigned long	GPR[32];
+	float_reg_t		FPR[32];
+	
+} PPCRegisterList;
+
+// 68k entry point for PPC Call
+typedef void (*EnterPriviledgedModeProc)(PPCRegisterList* regList);
+
+// PPC procInfo
+enum
+{
+	uppEnterPriviledgedModeProcInfo = kCStackBased
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(PPCRegisterList*)))
+};
+
+// Normal entry point
+extern void EnterPPCSupervisor(PPCRegisterList* regList);
+
+
+
+#endif

Added: trunk/miboot/src/LowLevelBoot.c
===================================================================
--- trunk/miboot/src/LowLevelBoot.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/LowLevelBoot.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,617 @@
+#include <Types.h>
+#include <CodeFragments.h>
+#include <MixedMode.h>
+#include <OSUtils.h>
+#include <Processes.h>
+#include <Traps.h>
+#include <ShutDown.h>
+#if defined(__MWERKS__)
+#include <A4Stuff.h>
+#endif
+#include <Video.h>
+#include <Palettes.h>
+#include <SCSI.h>
+#include <Power.h>
+#include <Gestalt.h>
+#include <LowMem.h>
+#include <Displays.h>
+#include <Devices.h>
+
+#include "LowLevelBoot.h"
+#include "bootx.h"
+#include "debug_text.h"
+#include "uLibc.h"
+
+#define LINUX_LOGO_COLORS		214
+#define CLOSE_VIDEO_DRIVERS		1
+#define FAKE_DEBUGGER			0
+#define FORCE_SCSI_ON			0
+#define DO_POWER_MANAGEMENT		0
+
+// This code will do the actual boot
+
+// Prototypes
+static void			PrepareDisplay(boot_infos_t *bi);
+static void			RemoveAnyHWCursor(short driverRefNum);
+static void			SetDefaultLinuxCTable(short driverRefNum);
+static void			GetColorMap(boot_infos_t* bi, GDHandle device);
+static void			SwitchTo8Bits(boot_infos_t* bi, GDHandle gDevice);
+static void			ForceUnmountAllVolumes(void);
+static Boolean		TrapAvailable(short theTrap);
+
+extern Ptr			get_physical(void* ptr);
+
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+extern dt_context*	 dct;
+
+
+#if defined(__GNUC__)
+inline void
+DisableInterrupts(void)
+{
+	__asm__ __volatile__ (
+		"ori.w	#0x700, %sr"
+	);
+}
+#else
+inline asm void
+DisableInterrupts(void)
+{
+	ori.w	#0x700, sr
+}
+#endif
+
+// Entry point called by BootX to install the shutdown proc.
+void
+low_boot(PPCRegisterList* regList, boot_infos_t* bi, void* ppc_glue)
+{
+//	EventRecord	event;
+	
+#if defined(__MWERKS__)
+//	EnterCodeResource();
+#endif
+
+//	SetZone(SystemZone());
+	
+	// Unmounts all volumes is not done by shudown proc
+	if (LMGetVCBQHdr()->qHead) {
+		dt_printf(dct, "Unmounting volumes...\n");
+		ForceUnmountAllVolumes();
+	}
+		
+	dt_printf(dct, "Preparing display...\n");
+	// Prepare displays (setup colormaps for 8 bits displays, remove HW cursors, ...)
+	PrepareDisplay(bi);
+	
+	// Let MacOS think we are a debugger and switch 68k emulator to supervisor first
+#if FAKE_DEBUGGER
+	DebuggerEnter();
+#endif
+	
+	// Put the emulator in supervisor mode
+	dt_printf(dct, "Entering 68k supervisor...\n");
+	EnterSupervisorMode();
+	
+#if FAKE_DEBUGGER
+	// Poll until no more OS events in the queue (safety)
+	do {
+		if (event.what == nullEvent)
+			break;
+		DebuggerPoll();
+	}
+	while(GetOSEvent(everyEvent, &event) != 0);
+#endif	
+	
+	// New BootX no longer care about logical display.
+	bi->logicalDisplayBase	= bi->dispDeviceBase;
+	
+	// Switch emulator interrupts off
+	DisableInterrupts();
+	
+	// Reset some pieces of hardware
+	if (ppc_glue)
+#if defined(__GNUC__)
+		__asm__ __volatile__ (
+			"move.l %1, -(%/sp)\n\t"
+			"move.l %2, -(%/sp)\n\t"
+			"jsr %0@"
+		:
+		:	"a" (ppc_glue),
+			"d" (dct),
+			"d" (bi)
+		:	"%a0", "%a1", "%a2", "%d0", "%d1", "%d2"
+		);
+#else
+		((pascal void(*)(dt_context*,boot_infos_t*))ppc_glue)(dct, bi);
+#endif
+	
+	// tempo
+	if (dct->visible) {
+		UInt32 i;
+		dt_printf(dct, "waiting a little bit so you can read all that stuff ...\n");
+		for(i=0;i<0x10000000; i++) {
+			(void)*((volatile char *)(0));
+		}
+	}
+	// Enter PPC supervisor (and boot kernel)
+	dt_printf(dct, "Entering PPC supervisor...\n");
+	EnterPPCSupervisor(regList);
+
+	// Should never reach this point
+#if FAKE_DEBUGGER
+	DebuggerExit();
+#endif
+}
+
+// This piece of code will unmount all volumes, including the system disk and
+// volumes with currently opened files.
+void
+ForceUnmountAllVolumes(void)
+{
+	QHdrPtr		vcbQueue;
+	VCBPtr		vcb;
+	
+	vcbQueue = LMGetVCBQHdr();
+	while((vcb = (VCBPtr)vcbQueue->qHead) != NULL) {
+		ParamBlockRec	pb;
+		
+		memset(&pb, 0, sizeof(ParamBlockRec));
+		pb.volumeParam.ioVRefNum	= vcb->vcbVRefNum;
+		pb.volumeParam.ioNamePtr	= NULL;
+		PBUnmountVolImmed(&pb);
+	}
+}
+
+// This routine will walk thru all MacOS displays, remove
+// hardware cursors and set colormaps to std linux colors for each
+// indexed device.
+void
+PrepareDisplay(boot_infos_t *bi)
+{
+#if CLOSE_VIDEO_DRIVERS
+	static short		sDriverList[16];
+	static Str255		sCFMError;
+	CFragConnectionID	driverLoaderLib;
+	Ptr					driverLoaderMain;
+	int					driver_count, i;
+#endif
+	
+	OSErr			err;
+	GDHandle		device;
+	
+	// We get default display infos.
+	device = GetMainDevice();
+	bi->dispDeviceRect[0]			= (**(**device).gdPMap).bounds.left;
+	bi->dispDeviceRect[1]			= (**(**device).gdPMap).bounds.top;
+	bi->dispDeviceRect[2]			= (**(**device).gdPMap).bounds.right;
+	bi->dispDeviceRect[3]			= (**(**device).gdPMap).bounds.bottom;
+	bi->dispDeviceDepth				= (**(**device).gdPMap).pixelSize;
+	bi->dispDeviceBase				= (UInt8 *)get_physical((UInt8 *)(**(**device).gdPMap).baseAddr);
+	bi->dispDeviceRowBytes			= (**(**device).gdPMap).rowBytes & 0x3FFF;
+	bi->dispDeviceRegEntryOffset	= NULL; // Not impl. yet
+	bi->logicalDisplayBase			= (UInt8 *)(**(**device).gdPMap).baseAddr;
+
+	// We loop all displays
+	device = GetDeviceList();
+#if CLOSE_VIDEO_DRIVERS
+	driver_count = 0;
+#endif
+	while(device)
+	{
+		if (TestDeviceAttribute(device, screenDevice) && !TestDeviceAttribute(device, noDriver))
+		{
+			short	refNum = (**device).gdRefNum;
+
+#if CLOSE_VIDEO_DRIVERS
+			int		found;			
+			// Add this driver to the list if it was not already in
+			found=0;
+			for(i=0; i<driver_count; i++)
+				if (sDriverList[i] == refNum)
+				{
+					found = true;
+					break;
+				}
+			if (!found)
+				sDriverList[driver_count++] = refNum;
+#endif
+				
+			// We need to switch to 8 bits since offb.c cannot handle anything else
+			// yet. (Only for the main device)
+			if (TestDeviceAttribute(device, mainScreen) && ((**(**device).gdPMap).pixelSize < 8))
+				SwitchTo8Bits(bi, device);
+			
+			// If the device has indexed colors, we install the standard Linux colormap
+			if ((**device).gdType == clutType)
+				SetDefaultLinuxCTable(refNum);
+				
+			// We try to blank the hardware cursor. Note that most devices will just make
+			// a transparent cursor, so it's a good thing, when not using a full-featured
+			// linux video driver, to avoid overriding the framebuffer outside of the
+			// defined rectangle. The border might actually contain the cursor.
+			RemoveAnyHWCursor(refNum);
+		}
+		device = GetNextDevice(device);
+	}
+	
+	// Get color map for main device
+	GetColorMap(bi, GetMainDevice());
+	
+#if CLOSE_VIDEO_DRIVERS
+	err = GetSharedLibrary("\x0f""DriverLoaderLib", kAnyCFragArch, kReferenceCFrag,
+						&driverLoaderLib, &driverLoaderMain, sCFMError);
+	if (err == noErr)
+	{
+		CFragSymbolClass	removeDrvrClass;
+		Ptr					removeDrvrProc;
+		
+		err = FindSymbol(driverLoaderLib, "\x0c""RemoveDriver", &removeDrvrProc, &removeDrvrClass);
+		if (err == noErr)
+		{
+			enum
+			{
+				uppRemoveDriverProcInfo = kCStackBased
+					| RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
+					| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
+					| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean)))
+			};
+			
+			UniversalProcPtr	removeDriverUPP = 
+				NewRoutineDescriptorTrap(	(ProcPtr)removeDrvrProc,
+								 			uppRemoveDriverProcInfo,
+											kPowerPCISA);
+			
+			// Close all video drivers
+			for (i=0; i<driver_count; i++)
+			{
+				CloseDriver(sDriverList[i]);
+#if defined(__GNUC__)
+				__asm__ __volatile__ (
+					"move.w %2, -(%/sp)\n\t"
+					"move.w %1, -(%/sp)\n\t"
+					"jsr %0@\n\t"
+					"addq.w #4, %/sp"
+				:
+				:	"a" (removeDriverUPP),
+					"d" (sDriverList[i]),
+					"d" (false)
+				:	"%a0", "%a1", "%a2", "%d0", "%d1", "%d2"
+				);
+#else
+				((OSErr (*)(short, Boolean))(removeDriverUPP))(sDriverList[i], false);
+#endif
+			}
+		}
+	}
+#endif
+}
+
+
+// Gather some infos about the current MacOS main display. This function
+// was originally in BootX.c (get_display_infos)
+void
+GetColorMap(boot_infos_t* bi, GDHandle device)
+{
+	if ((**device).gdType == clutType)
+	{
+		unsigned short*		colors = (unsigned short*)(((unsigned long)bi) + bi->dispDeviceColorsOffset);
+		CntrlParam			param;		
+		VDSetEntryRecord	hwGetEntry;
+		int					i;
+		OSErr				err;
+		static ColorSpec	sTempColors[256];
+		
+		memset(&param, 0, sizeof(CntrlParam));	
+		memset(&hwGetEntry, 0, sizeof(VDSetEntryRecord));
+		
+		param.csCode = cscGetEntries;
+		param.ioCRefNum = (**device).gdRefNum;
+		hwGetEntry.csTable = sTempColors;
+		hwGetEntry.csStart = 0;
+		hwGetEntry.csCount = 255;	// csCount is 0 based !!
+		*((VDSetEntryRecord **)&param.csParam[0]) = &hwGetEntry;
+		err = PBStatusSync((ParmBlkPtr)&param);
+		if (err == noErr)
+			for (i=0; i<256; i++)
+			{
+				*(colors++) = sTempColors[i].rgb.red;
+				*(colors++) = sTempColors[i].rgb.green;
+				*(colors++) = sTempColors[i].rgb.blue;
+			}
+		else
+			bi->dispDeviceColorsOffset = 0;
+		
+	} else
+		bi->dispDeviceColorsOffset = 0;
+}
+
+// Here, we switch the display to 8 bits using driver calls
+void
+SwitchTo8Bits(boot_infos_t* bi, GDHandle gDevice)
+{
+	// Lookup the modes supported by he video driver, looking for 8 bits
+	CntrlParam						param;
+	VDVideoParametersInfoRec		hwVideoParams;
+	VDPageInfo						hwModeSet;
+	VDSwitchInfoRec					hwModeGet;
+	VPBlock							hwVP;
+	short							i;
+	short							foundDepth;
+	OSErr							err;
+	
+	memset(&param, 0, sizeof(CntrlParam));	
+	memset(&hwModeSet, 0, sizeof(VDPageInfo));	
+	memset(&hwModeGet, 0, sizeof(VDSwitchInfoRec));	
+
+		
+	param.csCode = cscGetCurMode;
+	param.ioCRefNum = (**gDevice).gdRefNum;
+	*((VDSwitchInfoRec **)&param.csParam[0]) = &hwModeGet;
+	err = PBStatusSync((ParmBlkPtr)&param);
+	if (err != noErr)
+		return;
+	
+	foundDepth = 0;
+	for (i=kDepthMode1; i<=kDepthMode6; i++)
+	{
+		memset(&hwVideoParams, 0, sizeof(VDVideoParametersInfoRec));	
+		memset(&hwVP, 0, sizeof(VPBlock));	
+		hwVideoParams.csDisplayModeID	= hwModeGet.csData;
+		hwVideoParams.csDepthMode		= i;
+		hwVideoParams.csVPBlockPtr		= &hwVP;
+		param.csCode = cscGetVideoParameters;
+		param.ioCRefNum = (**gDevice).gdRefNum;
+		*((VDVideoParametersInfoRec **)&param.csParam[0]) = &hwVideoParams;
+		err = PBStatusSync((ParmBlkPtr)&param);
+		if (err == noErr)
+		{
+			if (hwVP.vpPixelSize == 8)
+			{
+				foundDepth = i;
+				break;
+			}
+		}
+	}
+	if (foundDepth != 0)
+	{
+		hwModeSet.csMode	= foundDepth;
+		hwModeSet.csPage	= 0;
+		param.csCode = cscSetMode;
+		param.ioCRefNum = (**gDevice).gdRefNum;
+		*((VDPageInfo **)&param.csParam[0]) = &hwModeSet;
+		err = PBControlSync((ParmBlkPtr)&param);
+		if (err == noErr)
+		{
+			(**gDevice).gdType	= clutType;
+			(**gDevice).gdMode	= foundDepth;
+			bi->dispDeviceDepth		= hwVP.vpPixelSize;
+			bi->logicalDisplayBase	= (UInt8 *)hwModeSet.csBaseAddr;
+			bi->dispDeviceBase		= (UInt8 *)get_physical((UInt8 *)hwModeSet.csBaseAddr);
+			bi->dispDeviceRowBytes	= hwVP.vpRowBytes & 0x3FFF;
+
+		}
+	}
+}
+
+// Ask the display driver if it supports hardware cursor and remove it.
+void
+RemoveAnyHWCursor(short driverRefNum)
+{
+	CntrlParam						param;
+	VDSupportsHardwareCursorRec		hwCursQuery;
+	VDDrawHardwareCursorRec			hwCursSet;
+	OSErr							err;
+	void*							genericPtr;
+	
+
+	memset(&param, 0, sizeof(CntrlParam));	
+	memset(&hwCursQuery, 0, sizeof(VDSupportsHardwareCursorRec));	
+	memset(&hwCursSet, 0, sizeof(VDDrawHardwareCursorRec));	
+	param.csCode = cscSupportsHardwareCursor;
+	param.ioCRefNum = driverRefNum;
+	*((VDSupportsHardwareCursorRec **)&param.csParam[0]) = &hwCursQuery;
+	err = PBStatusSync((ParmBlkPtr)&param);
+	if (err != noErr)
+		return;
+	
+	if (!hwCursQuery.csSupportsHardwareCursor)
+		return;
+	
+	memset(&param, 0, sizeof(CntrlParam));	
+	memset(&hwCursSet, 0, sizeof(VDDrawHardwareCursorRec));	
+	param.csCode = cscDrawHardwareCursor;
+	param.ioCRefNum = driverRefNum;
+	*((VDDrawHardwareCursorRec **)&param.csParam[0]) = &hwCursSet;
+	err = PBControlSync((ParmBlkPtr)&param);
+}
+
+// Install the linux default color map. We use direct driver calls since the
+// Palette Manager may prevent us from setting reserved MacOS colors.
+void
+SetDefaultLinuxCTable(short driverRefNum)
+{
+	static ColorSpec	sDefaultLinuxColors[]	=
+		{	0,	{	0x0000,	0x0000,	0x0000	},
+			1,	{	0x0000, 0x0000, 0xaaaa	},
+			2,	{	0x0000, 0xaaaa, 0x0000	},
+			3,	{	0x0000, 0xaaaa, 0xaaaa	},
+			4,	{	0xaaaa, 0x0000, 0x0000	},
+			5,	{	0xaaaa, 0x0000, 0xaaaa	},
+			6,	{	0xaaaa, 0xaaaa, 0x0000	},
+			7,	{	0xaaaa, 0xaaaa, 0xaaaa	},
+			8,	{	0x5555, 0x5555, 0x5555	},
+			9,	{	0x5555, 0x5555, 0xffff	},
+			10,	{	0x5555, 0xffff, 0x5555	},
+			11,	{	0x5555, 0xffff, 0xffff	},
+			12,	{	0xffff, 0x5555, 0x5555	},
+			13,	{	0xffff, 0x5555, 0xffff	},
+			14,	{	0xffff, 0xffff, 0x5555	},
+			15,	{	0xffff, 0xffff, 0xffff	} };
+			
+	CntrlParam						param;
+	VDSetEntryRecord				hwSetEntry;
+	OSErr							err;
+	unsigned long					temp;
+	ColorSpec*						logo_colors;
+	int								i;
+	memset(&param, 0, sizeof(CntrlParam));	
+	memset(&hwSetEntry, 0, sizeof(VDSetEntryRecord));
+	
+	param.csCode = cscSetEntries;
+	param.ioCRefNum = driverRefNum;
+	hwSetEntry.csTable = sDefaultLinuxColors;
+	hwSetEntry.csStart = 0;
+	hwSetEntry.csCount = 15;	// csCount is 0 based !!
+	*((VDSetEntryRecord **)&param.csParam[0]) = &hwSetEntry;
+	err = PBControlSync((ParmBlkPtr)&param);
+	
+	logo_colors = (ColorSpec *)NewPtrSys(sizeof(ColorSpec) * LINUX_LOGO_COLORS);
+	if (logo_colors == NULL)
+		goto failed;
+	for (i=0; i<LINUX_LOGO_COLORS; i++)
+	{
+		logo_colors[i].value		= i + 32;
+		logo_colors[i].rgb.red		= (linux_logo_red[i] << 8) | linux_logo_red[i];
+		logo_colors[i].rgb.green	= (linux_logo_green[i] << 8) | linux_logo_green[i]; 
+		logo_colors[i].rgb.blue		= (linux_logo_blue[i] << 8) | linux_logo_blue[i]; 
+	}
+	param.csCode = cscSetEntries;
+	param.ioCRefNum = driverRefNum;
+	hwSetEntry.csTable = logo_colors;
+	hwSetEntry.csStart = 32;
+	hwSetEntry.csCount = LINUX_LOGO_COLORS-1;	// csCount is 0 based !!
+	*((VDSetEntryRecord **)&param.csParam[0]) = &hwSetEntry;
+	err = PBControlSync((ParmBlkPtr)&param);
+	
+	DisposePtr((Ptr)logo_colors);
+	
+failed:
+
+	// Leave some time for the VBL to update the palette
+	Delay(10, &temp);
+}
+
+/*
+ * TrapAvailable (see Inside Mac VI 3-8)
+ */
+#define NumToolboxTraps() (								\
+		(NGetTrapAddress(_InitGraf, ToolTrap)			\
+				== NGetTrapAddress(0xAA6E, ToolTrap))	\
+			? 0x200 : 0x400								\
+	)
+#define GetTrapType(theTrap) (							\
+		(((theTrap) & 0x0800) != 0) ? ToolTrap : OSTrap	\
+	)
+
+static Boolean
+TrapAvailable(short theTrap)
+{
+		TrapType				trapType;
+		
+		trapType = GetTrapType(theTrap);
+		if (trapType == ToolTrap) {
+			theTrap &= 0x07FF;
+			if (theTrap >= NumToolboxTraps())
+				theTrap = _Unimplemented;
+		}
+		return (
+			NGetTrapAddress(theTrap, trapType)
+			!= NGetTrapAddress(_Unimplemented, ToolTrap)
+		);
+}
+
+
+
+unsigned char linux_logo_red[] = {
+  0x02, 0x9E, 0xE9, 0xC4, 0x50, 0xC9, 0xC4, 0xE9,
+  0x65, 0xE3, 0xC2, 0x25, 0xA4, 0xEC, 0x90, 0xA6,
+  0xC4, 0x6A, 0xD1, 0xF3, 0x12, 0xED, 0xA0, 0xC2,
+  0xB8, 0xD5, 0xDB, 0xD2, 0x3E, 0x16, 0xEB, 0x54,
+  0xA9, 0xCD, 0xF5, 0x0A, 0xBA, 0xB3, 0xDC, 0x74,
+  0xCE, 0xF6, 0xD3, 0xC5, 0xEA, 0xB8, 0xED, 0x5E,
+  0xE5, 0x26, 0xF4, 0xA9, 0x82, 0x94, 0xE6, 0x38,
+  0xF2, 0x0F, 0x7F, 0x49, 0xE5, 0xF4, 0xD3, 0xC3,
+  0xC2, 0x1E, 0xD5, 0xC6, 0xA4, 0xFA, 0x0A, 0xBA,
+  0xD4, 0xEB, 0xEA, 0xEC, 0xA8, 0xBC, 0xB4, 0xDC,
+  0x84, 0xE4, 0xCE, 0xEC, 0x92, 0xCD, 0xDC, 0x8B,
+  0xCC, 0x1E, 0xF6, 0xB2, 0x60, 0x2A, 0x96, 0x52,
+  0x0F, 0xBD, 0xFA, 0xCC, 0xB8, 0x7A, 0x4C, 0xD2,
+  0x06, 0xEF, 0x44, 0x64, 0xF4, 0xBA, 0xCE, 0xE6,
+  0x8A, 0x6F, 0x3C, 0x70, 0x7C, 0x9C, 0xBA, 0xDF,
+  0x2C, 0x4D, 0x3B, 0xCA, 0xDE, 0xCE, 0xEE, 0x46,
+  0x6A, 0xAC, 0x96, 0xE5, 0x96, 0x7A, 0xBA, 0xB6,
+  0xE2, 0x7E, 0xAA, 0xC5, 0x96, 0x9E, 0xC2, 0xAA,
+  0xDA, 0x35, 0xB6, 0x82, 0x88, 0xBE, 0xC2, 0x9E,
+  0xB4, 0xD5, 0xDA, 0x9C, 0xA0, 0xD0, 0xA8, 0xC7,
+  0x72, 0xF2, 0xDB, 0x76, 0xDC, 0xBE, 0xAA, 0xF4,
+  0x87, 0x2F, 0x53, 0x8E, 0x36, 0xCE, 0xE6, 0xCA,
+  0xCB, 0xE4, 0xD6, 0xAA, 0x42, 0x5D, 0xB4, 0x59,
+  0x1C, 0xC8, 0x96, 0x6C, 0xDA, 0xCE, 0xE6, 0xCB,
+  0x96, 0x16, 0xFA, 0xBE, 0xAE, 0xFE, 0x6E, 0xD6,
+  0xCE, 0xB6, 0xE5, 0xED, 0xDB, 0xDC, 0xF4, 0x72,
+  0x1F, 0xAE, 0xE6, 0xC2, 0xCA, 0xC4
+};
+
+unsigned char linux_logo_green[] = {
+  0x02, 0x88, 0xC4, 0x85, 0x44, 0xA2, 0xA8, 0xE5,
+  0x65, 0xA6, 0xC2, 0x24, 0xA4, 0xB4, 0x62, 0x86,
+  0x94, 0x44, 0xD2, 0xB6, 0x12, 0xD4, 0x73, 0x96,
+  0x92, 0x95, 0xB2, 0xC2, 0x36, 0x0E, 0xBC, 0x54,
+  0x75, 0xA5, 0xF5, 0x0A, 0xB2, 0x83, 0xC2, 0x74,
+  0x9B, 0xBD, 0xA2, 0xCA, 0xDA, 0x8C, 0xCB, 0x42,
+  0xAC, 0x12, 0xDA, 0x7B, 0x54, 0x94, 0xD2, 0x24,
+  0xBE, 0x06, 0x65, 0x33, 0xBB, 0xBC, 0xAB, 0x8C,
+  0x92, 0x1E, 0x9B, 0xB6, 0x6E, 0xFB, 0x04, 0xA2,
+  0xC8, 0xBD, 0xAD, 0xEC, 0x92, 0xBC, 0x7B, 0x9D,
+  0x84, 0xC4, 0xC4, 0xB4, 0x6C, 0x93, 0xA3, 0x5E,
+  0x8D, 0x13, 0xD6, 0x82, 0x4C, 0x2A, 0x7A, 0x5A,
+  0x0D, 0x82, 0xBB, 0xCC, 0x8B, 0x6A, 0x3C, 0xBE,
+  0x06, 0xC4, 0x44, 0x45, 0xDB, 0x96, 0xB6, 0xDE,
+  0x8A, 0x4D, 0x3C, 0x5A, 0x7C, 0x9C, 0xAA, 0xCB,
+  0x1C, 0x4D, 0x2E, 0xB2, 0xBE, 0xAA, 0xDE, 0x3E,
+  0x6A, 0xAC, 0x82, 0xE5, 0x72, 0x62, 0x92, 0x9E,
+  0xCA, 0x4A, 0x8E, 0xBE, 0x86, 0x6B, 0xAA, 0x9A,
+  0xBE, 0x34, 0xAB, 0x76, 0x6E, 0x9A, 0x9E, 0x62,
+  0x76, 0xCE, 0xD3, 0x92, 0x7C, 0xB8, 0x7E, 0xC6,
+  0x5E, 0xE2, 0xC3, 0x54, 0xAA, 0x9E, 0x8A, 0xCA,
+  0x63, 0x2D, 0x3B, 0x8E, 0x1A, 0x9E, 0xC2, 0xA6,
+  0xCB, 0xDC, 0xD6, 0x8E, 0x26, 0x5C, 0xB4, 0x45,
+  0x1C, 0xB8, 0x6E, 0x4C, 0xBC, 0xAE, 0xD6, 0x92,
+  0x63, 0x16, 0xF6, 0x8C, 0x7A, 0xFE, 0x6E, 0xBA,
+  0xC6, 0x86, 0xAA, 0xAE, 0xDB, 0xA4, 0xD4, 0x56,
+  0x0E, 0x6E, 0xB6, 0xB2, 0xBE, 0xBE
+};
+
+
+unsigned char linux_logo_blue[] = {
+  0x04, 0x28, 0x10, 0x0B, 0x14, 0x14, 0x74, 0xC7,
+  0x64, 0x0E, 0xC3, 0x24, 0xA4, 0x0C, 0x10, 0x20,
+  0x0D, 0x04, 0xD1, 0x0D, 0x13, 0x22, 0x0A, 0x40,
+  0x14, 0x0C, 0x11, 0x94, 0x0C, 0x08, 0x0B, 0x56,
+  0x09, 0x47, 0xF4, 0x0B, 0x9C, 0x07, 0x54, 0x74,
+  0x0F, 0x0C, 0x0F, 0xC7, 0x6C, 0x14, 0x14, 0x11,
+  0x0B, 0x04, 0x12, 0x0C, 0x05, 0x94, 0x94, 0x0A,
+  0x34, 0x09, 0x14, 0x08, 0x2F, 0x15, 0x19, 0x11,
+  0x28, 0x0C, 0x0B, 0x94, 0x08, 0xFA, 0x08, 0x7C,
+  0xBC, 0x15, 0x0A, 0xEC, 0x64, 0xBB, 0x0A, 0x0C,
+  0x84, 0x2C, 0xA0, 0x15, 0x10, 0x0D, 0x0B, 0x0E,
+  0x0A, 0x07, 0x10, 0x3C, 0x24, 0x2C, 0x28, 0x5C,
+  0x0A, 0x0D, 0x0A, 0xC1, 0x22, 0x4C, 0x10, 0x94,
+  0x04, 0x0F, 0x45, 0x08, 0x31, 0x54, 0x3C, 0xBC,
+  0x8C, 0x09, 0x3C, 0x18, 0x7C, 0x9C, 0x7C, 0x91,
+  0x0C, 0x4D, 0x17, 0x74, 0x0C, 0x48, 0x9C, 0x3C,
+  0x6A, 0xAC, 0x5C, 0xE3, 0x29, 0x3C, 0x2C, 0x7C,
+  0x6C, 0x04, 0x14, 0xA9, 0x74, 0x07, 0x2C, 0x74,
+  0x4C, 0x34, 0x97, 0x5C, 0x38, 0x0C, 0x5C, 0x04,
+  0x0C, 0xBA, 0xBC, 0x78, 0x18, 0x88, 0x24, 0xC2,
+  0x3C, 0xB4, 0x87, 0x0C, 0x14, 0x4C, 0x3C, 0x10,
+  0x17, 0x2C, 0x0A, 0x8C, 0x04, 0x1C, 0x44, 0x2C,
+  0xCD, 0xD8, 0xD4, 0x34, 0x0C, 0x5B, 0xB4, 0x1E,
+  0x1D, 0xAC, 0x24, 0x18, 0x20, 0x5C, 0xB4, 0x1C,
+  0x09, 0x14, 0xFC, 0x0C, 0x10, 0xFC, 0x6C, 0x7C,
+  0xB4, 0x1C, 0x15, 0x17, 0xDB, 0x18, 0x21, 0x24,
+  0x04, 0x04, 0x44, 0x8C, 0x8C, 0xB7
+};
+

Added: trunk/miboot/src/LowLevelBoot.h
===================================================================
--- trunk/miboot/src/LowLevelBoot.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/LowLevelBoot.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,19 @@
+#ifndef __LOW_LEVEL_BOOT_H__
+#define __LOW_LEVEL_BOOT_H__
+
+#include "EnterPPCSupervisor.h"
+#include "bootx.h"
+
+extern void low_boot(PPCRegisterList* regList, boot_infos_t* bi, void* ppc_glue);
+
+// PPC procInfo
+enum
+{
+	uppLowLevelBootPPCProcInfo = kPascalStackBased
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(void*)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(boot_infos_t*)))
+};
+
+
+
+#endif

Added: trunk/miboot/src/bootstrap.S
===================================================================
--- trunk/miboot/src/bootstrap.S	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/bootstrap.S	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,252 @@
+/* This is BootX boostrap. This code is called by BootX in supervisor mode
+ * with whatever mappings have been set by MacOS.
+ *
+ * The unmangler will first move itself up in memory in case it's current location
+ * overlaps the destination of the kernel. The boostrap copies itself
+ * and jump to the new bootstrap code.
+ *
+ * Note that all "decisions" regarding this copy are taken by BootX, the stack
+ * pointer (%r1) is already set to the destination stack for the kernel
+ * (the boostrap has no stack).
+ *
+ * Then, it will copy kernel pages to their destination from a map passed in
+ * by BootX. This map is appended to the unmangler and a pointer to it is
+ * passed in %r9 (pointer to the destination location of the unmangler).
+ * This map is actually a kind of "script" with a serie of copy operations
+ * to perform (a list of src/dest/size entries).
+ *
+ * Registers on entry:
+ *
+ * %r2  = 1 on entry by BootX
+ * %r3  = 0x426f6f58	('BooX')
+ * %r4  = pointer to boot_infos (in kernel destination)
+ * %r5  = fb address (for BAT mapping) (unimplemented)
+ * %r6  = physical address of me
+ * %r7  = physical address where I must be copied.
+ * %r8  = size to copy (size of unmangler)
+ * %r9  = unmangle map (pointer to list of copy operations)
+ * %r10 = kernel entry in destination
+ * %r11 = setup BAT mapping for fb (unimplemented)
+ *
+ * The unmangle map is a list of tuples of 3 longs each: a source address,
+ * a destination address, and a size. A size of zero indicates the end of
+ * the list.
+ *
+ * Portions of this code from Gabriel Paubert's PReP bootloader, other
+ * portions from the Linux kernel itself (arch/ppc/kernel/head.S)
+ *
+ */
+
+	.toc
+
+#include "processor.h"
+
+#define DISABLE_COPY	0
+
+#ifndef BROKEN_THIRD_PARTY_CARDS
+#define BROKEN_THIRD_PARTY_CARDS	0
+#endif
+
+#if BROKEN_THIRD_PARTY_CARDS
+#define __sync(x)		\
+	li %r0,0;			\
+	cmpwi %r0,0;			\
+	bne+ toto##x;		\
+	sync;				\
+toto##x:
+#else
+#define __sync(x)		sync
+#endif
+	
+
+/*
+ * void start(void);
+ */
+	.csect start[DS]
+	.globl start
+start:
+	.long .start, TOC[tc0], 0
+
+	.csect .start[PR]
+	.globl .start
+.start:
+first_bootstrap:	
+	/* Disable interrupts (clear MSR_EE). rlwinm is more "smart"
+	   but less readable (our constants are bit masks). */
+	mfmsr	%r0
+	ori		%r0,%r0,MSR_EE|MSR_ME
+	xori	%r0,%r0,MSR_EE|MSR_ME
+	mtmsr	%r0
+	__sync(0)
+
+	/* Check if MMU was already turned off */
+	cmplwi	%cr0,%r2,0
+	beq		already_off
+
+	/* turn the MMU off */
+	mfmsr	%r0
+	ori		%r0,%r0,MSR_IR|MSR_DR	/* |MSR_IP */
+	li		%r2,0
+	xori	%r0,%r0,MSR_IR|MSR_DR	/* |MSR_IP */
+	mtsrr0	%r6
+	mtsrr1	%r0
+	__sync(1)		/* I heard that some 601 will like this one */
+	rfi
+
+already_off:
+	/* save some parameters */	
+	mr		%r31,%r3
+	mr		%r30,%r4
+	mr		%r29,%r5
+
+	/* flush TLBs, ivalidate BATs */
+	bl		flush_tlb
+	bl		inval_BATs
+	bl		reset_segs
+	
+#if !DISABLE_COPY
+	/* Need to copy myself ? */
+	cmpw	%r6,%r7
+	beq		skip_copy
+	
+	/* Copy ourselves */
+	mr		%r3,%r7
+	mr		%r4,%r6
+	mr		%r5,%r8
+	li		%r6,0
+	bl		copy_and_flush
+	
+	mr		%r6, %r7		/* update address of me */
+	mr		%r3,%r31		/* restore parameters */
+	mr		%r4,%r30
+	mr		%r5,%r29
+	li		%r2,0		/* not necessary since no code here changes it, but... */
+	mtlr	%r7			/* Jump to copy of me (*) */
+	blr
+	
+/* (*) note that we jump at the beginning of the copy. We could jump
+       to skip_copy directly if CW knew how to calculate the offset
+       directly in the inline assembler. 
+ */
+#endif
+ 
+skip_copy:
+	
+#if !DISABLE_COPY
+	/* Call unmangle code */
+	bl		unmangle_kernel
+#endif
+	
+	/* Jump to kernel */
+	mr		%r3,%r31			/* restore parameters */
+	mr		%r4,%r30
+	li		%r5,0			/* clear %r5 */
+	mtlr	%r10
+	blr
+
+#if !DISABLE_COPY
+
+/* Unmangle kernel code. This routine will read the array prepared by
+ * BootX and follow instructions in it for copying kernel pages until
+ * the kernel is fully reconstitued
+ */
+unmangle_kernel:
+ 	mflr	%r13
+unmangle_loop:	
+ 	lwz		%r4,0(%r9)
+ 	lwz		%r3,4(%r9)
+ 	lwz		%r5,8(%r9)
+ 	li		%r6,0
+ 	addi	%r9,%r9,12
+ 	cmpwi	%r5,0
+ 	beq		unmangle_finish
+ 	bl		copy_and_flush
+ 	b		unmangle_loop
+unmangle_finish:
+	mtlr	%r13
+ 	blr
+
+/*
+ * Copy routine used to copy a piece of code and flush and invalidate
+ * the caches as needed.
+ * %r3 = dest addr, %r4 = source addr, %r5 = copy limit, %r6 = start offset
+ * on exit, %r3, %r4, %r5 are unchanged, %r6 is updated to be >= %r5.
+ */
+copy_and_flush:
+	addi	%r5,%r5,-4
+	addi	%r6,%r6,-4
+l4:
+	li	%r0,8
+	mtctr	%r0
+l3:
+	addi	%r6,%r6,4			/* copy a cache line */
+	lwzx	%r0,%r6,%r4
+	stwx	%r0,%r6,%r3
+	bdnz	l3
+	dcbst	%r6,%r3			/* write it to memory */
+	__sync(3)
+	icbi	%r6,%r3			/* flush the icache line */
+	cmplw	%r6,%r5
+	blt		l4
+	isync
+	addi	%r5,%r5,4
+	addi	%r6,%r6,4
+	blr
+
+#endif
+
+/* Routine for invalidating all BATs */
+inval_BATs:
+	li		%r3,0
+	mfspr	%r28,PVR
+	rlwinm	%r28,%r28,16,16,31		/* %r28 = 1 for 601, 4 for 604 */
+	cmpwi	%r28,1
+	beq		is_601_2
+	mtdbatu 0,%r3
+	mtdbatu 1,%r3
+	mtdbatu 2,%r3
+	mtdbatu 3,%r3
+is_601_2:
+	mtibatu 0,%r3
+	mtibatl	0,%r3
+	mtibatu 1,%r3
+	mtibatl 1,%r3
+	mtibatu 2,%r3
+	mtibatl 2,%r3
+	mtibatu 3,%r3
+	mtibatl 3,%r3
+	blr
+
+/* Resets the segment registers to a known state */
+reset_segs:
+	li		%r0,16		/* load up segment register values */
+	mtctr	%r0		/* for context 0 */
+	lis	%r3,0x2000	/* Ku = 1, VSID = 0 */
+	li	%r4,0
+s_loop:
+	mtsrin	%r3,%r4
+	addi	%r3,%r3,1		/* increment VSID */
+	addis	%r4,%r4,0x1000	/* address of next segment */
+	bdnz	s_loop
+	blr
+
+/* Due to the PPC architecture (and according to the specifications), a
+ * series of tlbie which goes through a whole 256 MB segment always flushes 
+ * the whole TLB. This is obviously overkill and slow, but who cares ? 
+ * It takes about 1 ms on a 200 MHz 603e and works even if residual data 
+ * get the number of TLB entries wrong.
+ */
+flush_tlb:
+	lis		%r28,0x1000
+flush_tlb_loop:
+	addic.  %r28,%r28,-0x1000
+	tlbie	%r28
+	blt		flush_tlb_loop
+	
+/* tlbsync is not implemented on 601, so use sync which seems to be a superset
+ * of tlbsync in all cases and do not bother with CPU dependant code
+ */
+	__sync(4)
+	blr					
+
+

Added: trunk/miboot/src/bootx.h
===================================================================
--- trunk/miboot/src/bootx.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/bootx.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,136 @@
+/*
+ * This file describes the structure passed from the BootX application
+ * (for MacOS) when it is used to boot Linux.
+ *
+ * Written by Benjamin Herrenschmidt.
+ */
+
+
+#ifndef __ASM_BOOTX_H__
+#define __ASM_BOOTX_H__
+
+#ifdef macintosh
+#include <Types.h>
+#include "linux_type_defs.h"
+#endif
+
+#ifdef macintosh
+/* All this requires PowerPC alignment */
+#pragma options align=power
+#endif
+
+/* On kernel entry:
+ *
+ * r3 = 0x426f6f58    ('BooX')
+ * r4 = pointer to boot_infos
+ * r5 = NULL
+ *
+ * Data and instruction translation disabled, interrupts
+ * disabled, kernel loaded at physical 0x00000000 on PCI
+ * machines (will be different on NuBus).
+ */
+
+#define BOOT_INFO_VERSION               5
+#define BOOT_INFO_COMPATIBLE_VERSION    1
+
+/* Bit in the architecture flag mask. More to be defined in
+   future versions. Note that either BOOT_ARCH_PCI or
+   BOOT_ARCH_NUBUS is set. The other BOOT_ARCH_NUBUS_xxx are
+   set additionally when BOOT_ARCH_NUBUS is set.
+ */
+#define BOOT_ARCH_PCI                   0x00000001UL
+#define BOOT_ARCH_NUBUS                 0x00000002UL
+#define BOOT_ARCH_NUBUS_PDM             0x00000010UL
+#define BOOT_ARCH_NUBUS_PERFORMA        0x00000020UL
+#define BOOT_ARCH_NUBUS_POWERBOOK       0x00000040UL
+
+/*  Maximum number of ranges in phys memory map */
+#define MAX_MEM_MAP_SIZE				26
+
+/* This is the format of an element in the physical memory map. Note that
+   the map is optional and current BootX will only build it for pre-PCI
+   machines */
+typedef struct boot_info_map_entry
+{
+    __u32       physAddr;                /* Physical starting address */
+    __u32       size;                    /* Size in bytes */
+} boot_info_map_entry_t;
+
+
+/* Here are the boot informations that are passed to the bootstrap
+ * Note that the kernel arguments and the device tree are appended
+ * at the end of this structure. */
+typedef struct boot_infos
+{
+    /* Version of this structure */
+    __u32       version;
+    /* backward compatible down to version: */
+    __u32       compatible_version;
+    
+    /* NEW (vers. 2) this holds the current _logical_ base addr of
+       the frame buffer (for use by early boot message) */
+    __u8*       logicalDisplayBase;
+
+    /* NEW (vers. 4) Apple's machine identification */
+    __u32       machineID;
+
+    /* NEW (vers. 4) Detected hw architecture */
+    __u32       architecture;
+    
+    /* The device tree (internal addresses relative to the beginning of the tree,
+     * device tree offset relative to the beginning of this structure).
+     * On pre-PCI macintosh (BOOT_ARCH_PCI bit set to 0 in architecture), this
+     * field is 0.
+     */
+    __u32       deviceTreeOffset;        /* Device tree offset */
+    __u32       deviceTreeSize;          /* Size of the device tree */
+        
+    /* Some infos about the current MacOS display */
+    __u32       dispDeviceRect[4];       /* left,top,right,bottom */
+    __u32       dispDeviceDepth;         /* (8, 16 or 32) */
+    __u8*       dispDeviceBase;          /* base address (physical) */
+    __u32       dispDeviceRowBytes;      /* rowbytes (in bytes) */
+    __u32       dispDeviceColorsOffset;  /* Colormap (8 bits only) or 0 (*) */
+    /* Optional offset in the registry to the current
+     * MacOS display. (Can be 0 when not detected) */
+     __u32      dispDeviceRegEntryOffset;
+
+    /* Optional pointer to boot ramdisk (offset from this structure) */
+    __u32       ramDisk;
+    __u32       ramDiskSize;             /* size of ramdisk image */
+    
+    /* Kernel command line arguments (offset from this structure) */
+    __u32       kernelParamsOffset;
+    
+    /* ALL BELOW NEW (vers. 4) */
+    
+    /* This defines the physical memory. Valid with BOOT_ARCH_NUBUS flag
+       (non-PCI) only. On PCI, memory is contiguous and it's size is in the
+       device-tree. */
+    boot_info_map_entry_t
+    	        physMemoryMap[MAX_MEM_MAP_SIZE]; /* Where the phys memory is */
+    __u32       physMemoryMapSize;               /* How many entries in map */
+    
+				
+    /* The framebuffer size (optional, currently 0) */
+    __u32       frameBufferSize;         /* Represents a max size, can be 0. */
+    
+    /* NEW (vers. 5) */
+
+    /* Total params size (args + colormap + device tree + ramdisk) */
+    __u32       totalParamsSize;
+
+} boot_infos_t;
+
+/* (*) The format of the colormap is 256 * 3 * 2 bytes. Each color index is represented
+ * by 3 short words containing a 16 bits (unsigned) color component.
+ * Later versions may contain the gamma table for direct-color devices here.
+ */
+#define BOOTX_COLORTABLE_SIZE    (256UL*3UL*2UL)
+
+#ifdef macintosh
+#pragma options align=reset
+#endif
+
+#endif
+    

Added: trunk/miboot/src/debug_sprintf.c
===================================================================
--- trunk/miboot/src/debug_sprintf.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/debug_sprintf.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,228 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this
+software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *      @(#)subr_prf.c  8.3 (Berkeley) 1/21/94
+ *
+ *
+ *		Extracted vsprinf & adapted by BenH for MountX, Wed, June 3 1998.
+ *		Added support for pascal strings.
+ */
+
+#include <stdarg.h>
+
+typedef unsigned long u_long;
+typedef unsigned int u_int;
+typedef unsigned char u_char;
+
+//#define NULL    ((void *)0)
+#define NBBY    8
+
+int vsprintf(char *buf, const char *cfmt, va_list ap);
+static char *ksprintn(u_long ul, int base, int *lenp, int prec);
+
+int sprintf(char * s, const char * format, ...)
+{
+	va_list	params;
+	int		r;
+	
+	va_start(params, format);
+	r = vsprintf(s, format, params);
+	va_end(params);
+	
+	return r;
+}
+
+
+/*
+ * Scaled down version of sprintf(3).
+ */
+int
+vsprintf(char *buf, const char *cfmt, va_list ap)
+{
+        register const char *fmt = cfmt;
+        register char *p, *bp;
+        register int ch, base;
+        u_long ul;
+        int lflag, tmp, width, pstring;
+        int prec, precspec;
+        char padc;
+
+        for (bp = buf; ; ) {
+                padc = ' ';
+                width = 0;
+                prec = 0;
+                precspec = 0;
+                pstring = 0;
+                while ((ch = *(u_char *)fmt++) != '%')
+                        if ((*bp++ = (char)ch) == '\0')
+                                return ((bp - buf) - 1);
+
+                lflag = 0;
+reswitch:       switch (ch = *(u_char *)fmt++) {
+                case '0':
+                        padc = '0';
+                        goto reswitch;
+                case '1': case '2': case '3': case '4':
+                case '5': case '6': case '7': case '8': case '9':
+                        for (width = 0;; ++fmt) {
+                                width = width * 10 + ch - '0';
+                                ch = *fmt;
+                                if (ch < '0' || ch > '9')
+                                        break;
+                        }
+                        goto reswitch;
+                       
+                case '#':
+                		pstring = 1;
+                		goto reswitch;
+                case '*':
+                        width = va_arg(ap, int);
+                        goto reswitch;
+                case '.':
+                        precspec = 1;
+                        if (*fmt == '*') {
+                                prec = va_arg(ap, int);
+                                ++fmt;
+                                goto reswitch;
+                        }
+                        for (prec = 0;; ++fmt) {
+                                ch = *fmt;
+                                if (ch < '0' || ch > '9')
+                                        break;
+                                prec = prec * 10 + ch - '0';
+                        }
+                        goto reswitch;
+                case 'l':
+                        lflag = 1;
+                        goto reswitch;
+                /* case 'b': ... break; XXX */
+                case 'c':
+                        *bp++ = (char)va_arg(ap, int);
+                        break;
+                /* case 'r': ... break; XXX */
+                case 's':
+                        p = va_arg(ap, char *);
+                        if (pstring)
+                        {
+                        	prec = precspec ? ((prec < *p) ? prec : *p) : *p;
+                        	p++;
+                        	precspec = 1;
+                        }
+                        while ((!precspec || (--prec >= 0)) && ((*bp = *p++) != 0))
+                                ++bp;
+                        break;
+                case 'd':
+                        ul = (unsigned long)(lflag ? va_arg(ap, long) : va_arg(ap, int));
+                        if ((long)ul < 0) {
+                                *bp++ = (char)'-';
+                                ul = (unsigned long)(-(long)ul);
+                        }
+                        base = 10;
+                        goto number;
+                        break;
+                case 'o':
+                        ul = lflag ? va_arg(ap, u_long) : va_arg(ap,
+u_int);
+                        base = 8;
+                        goto number;
+                        break;
+                case 'u':
+                        ul = lflag ? va_arg(ap, u_long) : va_arg(ap,
+u_int);
+                        base = 10;
+                        goto number;
+                        break;
+                case 'p':
+                        *bp++ = '0';
+                        *bp++ = 'x';
+                        ul = (u_long)va_arg(ap, void *);
+                        base = 16;
+                        goto number;
+                case 'x':
+                case 'X':
+                        ul = lflag ? va_arg(ap, u_long) : va_arg(ap,
+u_int);
+                        base = 16;
+number:                 p = ksprintn(ul, base, &tmp, prec);
+                        if (width && (width -= tmp) > 0)
+                                while (width--)
+                                        *bp++ = padc;
+                        while ((ch = *p--) != 0)
+                                *bp++ = (char)ch;
+                        break;
+                default:
+                        *bp++ = '%';
+                        if (lflag)
+                                *bp++ = 'l';
+                        /* FALLTHROUGH */
+                case '%':
+                        *bp++ = (char)ch;
+                }
+        }
+}
+
+/*
+ * Put a number (base <= 16) in a buffer in reverse order; return an
+ * optional length and a pointer to the NULL terminated (preceded?)
+ * buffer.
+ */
+static char *
+ksprintn(u_long ul, int base, int *lenp, int prec)
+{                                       /* A long in base 8, plus NULL. */
+        char buf[sizeof(long) * NBBY / 3 + 4];
+        register char *p;
+		int i;
+        p = buf;
+        for(i=0;i<sizeof(buf);i++)
+     		buf[i] = 0;
+        do {
+                *++p = "0123456789abcdef"[ul % base];
+                ul /= base;
+        } while ((--prec > 0 || ul != 0) && p < buf + sizeof(buf) - 1);
+        if (lenp)
+                *lenp = p - buf;
+        return (p);
+}
+
+

Added: trunk/miboot/src/debug_text.c
===================================================================
--- trunk/miboot/src/debug_text.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/debug_text.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,558 @@
+#include "debug_text.h"
+
+#if __DEBUG_HAS_PRINTF__
+#include <stdarg.h>
+#endif
+
+#define cmapsz	(16*256)
+
+static unsigned char vga_font[cmapsz];
+
+static unsigned long expand_bits_8[16] = {
+	0x00000000,
+	0x000000ff,
+	0x0000ff00,
+	0x0000ffff,
+	0x00ff0000,
+	0x00ff00ff,
+	0x00ffff00,
+	0x00ffffff,
+	0xff000000,
+	0xff0000ff,
+	0xff00ff00,
+	0xff00ffff,
+	0xffff0000,
+	0xffff00ff,
+	0xffffff00,
+	0xffffffff
+};
+
+static unsigned long expand_bits_16[4] = {
+	0x00000000,
+	0x0000ffff,
+	0xffff0000,
+	0xffffffff
+};
+
+#if __DEBUG_HAS_PRINTF__
+
+extern int	sprintf(char * s, const char * format, ...);
+extern int	vsprintf(char *buf, const char *cfmt, va_list ap);
+
+static char __printf_buffer[2048];
+
+#endif /* __DEBUG_HAS_PRINTF__ */
+
+
+static void
+draw_byte_32(dt_context *ct, unsigned char *font, unsigned long *base)
+{
+	int l, bits;
+	
+	int fg = 0xFFFFFFFFUL;
+	int bg = 0x00000000UL;
+	
+	for (l = 0; l < 16; ++l) {
+		bits = *font++;
+		base[0] = (-(bits >> 7) & fg) ^ bg;
+		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
+		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
+		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
+		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
+		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
+		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
+		base[7] = (-(bits & 1) & fg) ^ bg;
+		base = (unsigned long *) ((char *)base + ct->row_bytes);
+	}
+}
+
+static void
+draw_byte_16(dt_context *ct, unsigned char *font, unsigned long *base)
+{
+	int l, bits;
+	
+	int fg = 0xFFFFFFFFUL;
+	int bg = 0x00000000UL;
+
+	for (l = 0; l < 16; ++l) {
+		bits = *font++;
+		base[0] = (expand_bits_16[bits >> 6] & fg) ^ bg;
+		base[1] = (expand_bits_16[(bits >> 4) & 3] & fg) ^ bg;
+		base[2] = (expand_bits_16[(bits >> 2) & 3] & fg) ^ bg;
+		base[3] = (expand_bits_16[bits & 3] & fg) ^ bg;
+		base = (unsigned long *) ((char *)base + ct->row_bytes);
+	}
+}
+
+static void
+draw_byte_8(dt_context *ct, unsigned char *font, unsigned long *base)
+{
+	int l, bits;
+	
+	int fg = 0xFFFFFFFFUL;
+	int bg = 0x00000000UL;
+
+	for (l = 0; l < 16; ++l) {
+		bits = *font++;
+		base[0] = (expand_bits_8[bits >> 4] & fg) ^ bg;
+		base[1] = (expand_bits_8[bits & 0xf] & fg) ^ bg;
+		base = (unsigned long *) ((char *)base + ct->row_bytes);
+	}
+}
+
+static void
+draw_byte(dt_context *ct, unsigned char c, long locX, long locY)
+{
+	unsigned char *base =	ct->base + ct->row_bytes * locY * 16 + (ct->depth >> 3) * locX * 8;
+	unsigned char *font =	&vga_font[((unsigned long)c) * 16];
+	
+	switch(ct->depth)
+	{
+		case 32:
+			draw_byte_32(ct, font, (unsigned long *)base);
+			break;
+		case 16:
+			draw_byte_16(ct, font, (unsigned long *)base);
+			break;
+		case 8:
+			draw_byte_8(ct, font, (unsigned long *)base);
+			break;
+	}
+}
+
+static void
+scroll_screen(dt_context* ct)
+{
+	unsigned long width			= ((ct->width) * (ct->depth >> 3)) >> 2;
+	int i,j;
+	
+	for (i=0; i<(ct->height - 16); i++) {
+		unsigned long *src	= (unsigned long *)(ct->base + ct->row_bytes * (i+16));
+		unsigned long *dest	= (unsigned long *)(ct->base + ct->row_bytes * i);
+		for(j=0; j<width; j++)
+			*(dest++) = *(src++);
+	}
+	for (i=(ct->siz_w-1)*16; i<(ct->siz_w*16); i++) {
+		unsigned long *dest	= (unsigned long *)(ct->base + ct->row_bytes * i);
+		for(j=0; j<width; j++)
+			*(dest++) = 0;
+	}
+}
+
+void
+dt_init(dt_context *ct)
+{
+	ct->pos_x 	= 0;
+	ct->pos_y 	= 0;
+	ct->siz_w	= ct->width / 8;
+	ct->siz_h	= ct->height / 16;
+}
+
+void
+dt_draw_char(dt_context *ct, char c)
+{
+	switch(c) {
+		case '\r':	ct->pos_x = 0;				break;
+		case '\n':	ct->pos_x = 0; ct->pos_y++;	break;
+		default:
+			draw_byte(ct, c, ct->pos_x++, ct->pos_y);
+			if (ct->pos_x >= ct->siz_w) {
+				ct->pos_x = 0;
+				ct->pos_y++;
+			}
+	}
+	while (ct->pos_y >= ct->siz_h) {
+		scroll_screen(ct);
+		ct->pos_y--;
+	}
+}
+
+void
+dt_draw_string(dt_context *ct, char *s)
+{
+	if (!ct->visible)
+		return;
+	while(*s)
+		dt_draw_char(ct, *(s++));
+}
+
+void
+dt_clear_screen(dt_context *ct)
+{
+	unsigned char *base 	= (unsigned char *)ct->base;
+	unsigned long width 	= ((ct->width) * (ct->depth >> 3)) >> 2;
+	int i,j;
+	
+	if (!ct->visible)
+		return;
+	for (i=0; i<ct->height; i++) {
+		unsigned long* line = (unsigned long *)(base + i * ct->row_bytes);
+		for(j=0; j<width; j++)
+			*(line++) = 0;
+	}
+}
+
+#if __DEBUG_HAS_PRINTF__
+
+int
+dt_printf(dt_context *ct, const char * format, ...)
+{
+	va_list				args;
+	int					len;
+
+	va_start(args, format);
+	len = vsprintf(__printf_buffer, format, args);
+	va_end(args);
+
+	if (len && ct->visible)
+		dt_draw_string(ct, __printf_buffer);
+
+	return len;		
+}
+
+#endif /* __DEBUG_HAS_PRINTF__ */
+
+static unsigned char vga_font[cmapsz] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 
+};

Added: trunk/miboot/src/debug_text.h
===================================================================
--- trunk/miboot/src/debug_text.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/debug_text.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,33 @@
+#ifndef __DEBUG_TEXT_H__
+#define __DEBUG_TEXT_H__
+
+#ifndef __DEBUG_HAS_PRINTF__
+#define __DEBUG_HAS_PRINTF__	1
+#endif
+
+typedef struct dt_context {
+	/* pre-initialised */
+	unsigned char*	base;
+	unsigned long	row_bytes;	/* in bytes */
+	unsigned long	depth;		/* 8, 16 or 32 */
+	unsigned long	width;		/* in pixels */
+	unsigned long	height;
+	unsigned long	visible;
+	
+	/* initialised by dt_init() */
+	unsigned long	siz_w, siz_h;
+	unsigned long	pos_x, pos_y;
+	
+} dt_context ;
+
+extern void dt_init(dt_context *ct);
+
+extern void dt_draw_char(dt_context *ct, char c);
+extern void dt_draw_string(dt_context *ct, char *s);
+extern void dt_clear_screen(dt_context *ct);
+
+#if __DEBUG_HAS_PRINTF__
+extern int	dt_printf(dt_context *ct, const char * format, ...);
+#endif
+
+#endif

Added: trunk/miboot/src/elf_loader_defs.h
===================================================================
--- trunk/miboot/src/elf_loader_defs.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/elf_loader_defs.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,521 @@
+#ifndef _MODIFIED_LINUX_ELF_H
+#define _MODIFIED_LINUX_ELF_H
+
+#include "linux_type_defs.h"
+
+// from asm-ppc/elf.h
+#define ELF_ARCH	EM_PPC
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+
+
+/* 32-bit ELF base types. */
+typedef __u32	Elf32_Addr;
+typedef __u16	Elf32_Half;
+typedef __u32	Elf32_Off;
+typedef __s32	Elf32_Sword;
+typedef __u32	Elf32_Word;
+
+/* 64-bit ELF base types. */
+typedef __u64	Elf64_Addr;
+typedef __u16	Elf64_Half;
+typedef __s16	Elf64_SHalf;
+typedef __u64	Elf64_Off;
+typedef __s64	Elf64_Sword;
+typedef __u64	Elf64_Word;
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL    0
+#define PT_LOAD    1
+#define PT_DYNAMIC 2
+#define PT_INTERP  3
+#define PT_NOTE    4
+#define PT_SHLIB   5
+#define PT_PHDR    6
+#define PT_LOPROC  0x70000000
+#define PT_HIPROC  0x7fffffff
+
+/* These constants define the different elf file types */
+#define ET_NONE   0
+#define ET_REL    1
+#define ET_EXEC   2
+#define ET_DYN    3
+#define ET_CORE   4
+#define ET_LOPROC 5
+#define ET_HIPROC 6
+
+/* These constants define the various ELF target machines */
+#define EM_NONE  0
+#define EM_M32   1
+#define EM_SPARC 2
+#define EM_386   3
+#define EM_68K   4
+#define EM_88K   5
+#define EM_486   6   /* Perhaps disused */
+#define EM_860   7
+
+#define EM_MIPS		8	/* MIPS R3000 (officially, big-endian only) */
+
+#define EM_MIPS_RS4_BE 10	/* MIPS R4000 big-endian */
+
+#define EM_PARISC      15	/* HPPA */
+
+#define EM_SPARC32PLUS 18	/* Sun's "v8plus" */
+
+#define EM_PPC	       20	/* PowerPC */
+
+#define EM_SPARCV9     43	/* SPARC v9 64-bit */
+
+/*
+ * This is an interim value that we will use until the committee comes
+ * up with a final number.
+ */
+#define EM_ALPHA	0x9026
+
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH 	15
+#define DT_SYMBOLIC	16
+#define DT_REL	        17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL  0
+#define STB_GLOBAL 1
+#define STB_WEAK   2
+
+#define STT_NOTYPE  0
+#define STT_OBJECT  1
+#define STT_FUNC    2
+#define STT_SECTION 3
+#define STT_FILE    4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+/* Symbolic values for the entries in the auxiliary table
+   put on the initial stack */
+#define AT_NULL   0	/* end of vector */
+#define AT_IGNORE 1	/* entry should be ignored */
+#define AT_EXECFD 2	/* file descriptor of program */
+#define AT_PHDR   3	/* program headers for program */
+#define AT_PHENT  4	/* size of program header entry */
+#define AT_PHNUM  5	/* number of program headers */
+#define AT_PAGESZ 6	/* system page size */
+#define AT_BASE   7	/* base address of interpreter */
+#define AT_FLAGS  8	/* flags */
+#define AT_ENTRY  9	/* entry point of program */
+#define AT_NOTELF 10	/* program is not ELF */
+#define AT_UID    11	/* real uid */
+#define AT_EUID   12	/* effective uid */
+#define AT_GID    13	/* real gid */
+#define AT_EGID   14	/* effective gid */
+#define AT_PLATFORM 15  /* string identifying CPU for optimizations */
+#define AT_HWCAP  16    /* arch dependent hints at CPU capabilities */
+
+typedef struct dynamic{
+  Elf32_Sword d_tag;
+  union{
+    Elf32_Sword	d_val;
+    Elf32_Addr	d_ptr;
+  } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+  Elf64_Word d_tag;		/* entry tag value */
+  union {
+    Elf64_Word d_val;
+    Elf64_Word d_ptr;
+  } d_un;
+} Elf64_Dyn;
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE	0
+#define R_386_32	1
+#define R_386_PC32	2
+#define R_386_GOT32	3
+#define R_386_PLT32	4
+#define R_386_COPY	5
+#define R_386_GLOB_DAT	6
+#define R_386_JMP_SLOT	7
+#define R_386_RELATIVE	8
+#define R_386_GOTOFF	9
+#define R_386_GOTPC	10
+#define R_386_NUM	11
+
+/*
+ * Sparc ELF relocation types
+ */
+#define	R_SPARC_NONE		0
+#define	R_SPARC_8		1
+#define	R_SPARC_16		2
+#define	R_SPARC_32		3
+#define	R_SPARC_DISP8		4
+#define	R_SPARC_DISP16		5
+#define	R_SPARC_DISP32		6
+#define	R_SPARC_WDISP30		7
+#define	R_SPARC_WDISP22		8
+#define	R_SPARC_HI22		9
+#define	R_SPARC_22		10
+#define	R_SPARC_13		11
+#define	R_SPARC_LO10		12
+#define	R_SPARC_GOT10		13
+#define	R_SPARC_GOT13		14
+#define	R_SPARC_GOT22		15
+#define	R_SPARC_PC10		16
+#define	R_SPARC_PC22		17
+#define	R_SPARC_WPLT30		18
+#define	R_SPARC_COPY		19
+#define	R_SPARC_GLOB_DAT	20
+#define	R_SPARC_JMP_SLOT	21
+#define	R_SPARC_RELATIVE	22
+#define	R_SPARC_UA32		23
+#define R_SPARC_PLT32		24
+#define R_SPARC_HIPLT22		25
+#define R_SPARC_LOPLT10		26
+#define R_SPARC_PCPLT32		27
+#define R_SPARC_PCPLT22		28
+#define R_SPARC_PCPLT10		29
+#define R_SPARC_10		30
+#define R_SPARC_11		31
+#define R_SPARC_WDISP16		40
+#define R_SPARC_WDISP19		41
+#define R_SPARC_7		43
+#define R_SPARC_5		44
+#define R_SPARC_6		45
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
+#define HWCAP_SPARC_STBAR       2
+#define HWCAP_SPARC_SWAP        4
+#define HWCAP_SPARC_MULDIV      8
+#define HWCAP_SPARC_V9		16
+
+
+/*
+ * 68k ELF relocation types
+ */
+#define R_68K_NONE	0
+#define R_68K_32	1
+#define R_68K_16	2
+#define R_68K_8		3
+#define R_68K_PC32	4
+#define R_68K_PC16	5
+#define R_68K_PC8	6
+#define R_68K_GOT32	7
+#define R_68K_GOT16	8
+#define R_68K_GOT8	9
+#define R_68K_GOT32O	10
+#define R_68K_GOT16O	11
+#define R_68K_GOT8O	12
+#define R_68K_PLT32	13
+#define R_68K_PLT16	14
+#define R_68K_PLT8	15
+#define R_68K_PLT32O	16
+#define R_68K_PLT16O	17
+#define R_68K_PLT8O	18
+#define R_68K_COPY	19
+#define R_68K_GLOB_DAT	20
+#define R_68K_JMP_SLOT	21
+#define R_68K_RELATIVE	22
+
+/*
+ * Alpha ELF relocation types
+ */
+#define R_ALPHA_NONE            0       /* No reloc */
+#define R_ALPHA_REFLONG         1       /* Direct 32 bit */
+#define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
+#define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
+#define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP          6       /* Add displacement to GP */
+#define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16          9       /* PC relative 16 bit */
+#define R_ALPHA_SREL32          10      /* PC relative 32 bit */
+#define R_ALPHA_SREL64          11      /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH         12      /* OP stack push */
+#define R_ALPHA_OP_STORE        13      /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB         14      /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT      15      /* OP stack right shift */
+#define R_ALPHA_GPVALUE         16
+#define R_ALPHA_GPRELHIGH       17
+#define R_ALPHA_GPRELLOW        18
+#define R_ALPHA_IMMED_GP_16     19
+#define R_ALPHA_IMMED_GP_HI32   20
+#define R_ALPHA_IMMED_SCN_HI32  21
+#define R_ALPHA_IMMED_BR_HI32   22
+#define R_ALPHA_IMMED_LO32      23
+#define R_ALPHA_COPY            24      /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
+#define R_ALPHA_RELATIVE        27      /* Adjust by program base */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses are below 2GB */
+
+
+typedef struct elf32_rel {
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+  Elf64_Addr r_offset;	/* Location at which to apply the action */
+  Elf64_Word r_info;	/* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+  Elf32_Sword	r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+  Elf64_Addr r_offset;	/* Location at which to apply the action */
+  Elf64_Word r_info;	/* index and type of relocation */
+  Elf64_Word r_addend;	/* Constant addend used to compute value */
+} Elf64_Rela;
+
+typedef struct elf32_sym{
+  Elf32_Word	st_name;
+  Elf32_Addr	st_value;
+  Elf32_Word	st_size;
+  unsigned char	st_info;
+  unsigned char	st_other;
+  Elf32_Half	st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym {
+  Elf32_Word st_name;		/* Symbol name, index in string tbl (yes, Elf32) */
+  unsigned char	st_info;	/* Type and binding attributes */
+  unsigned char	st_other;	/* No defined meaning, 0 */
+  Elf64_Half st_shndx;		/* Associated section index */
+  Elf64_Addr st_value;		/* Value of the symbol */
+  Elf64_Word st_size;		/* Associated symbol size */
+} Elf64_Sym;
+
+
+#define EI_NIDENT	16
+
+typedef struct elf32_hdr{
+  unsigned char	e_ident[EI_NIDENT];
+  Elf32_Half	e_type;
+  Elf32_Half	e_machine;
+  Elf32_Word	e_version;
+  Elf32_Addr	e_entry;  /* Entry point */
+  Elf32_Off	e_phoff;
+  Elf32_Off	e_shoff;
+  Elf32_Word	e_flags;
+  Elf32_Half	e_ehsize;
+  Elf32_Half	e_phentsize;
+  Elf32_Half	e_phnum;
+  Elf32_Half	e_shentsize;
+  Elf32_Half	e_shnum;
+  Elf32_Half	e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64_hdr {
+  unsigned char	e_ident[16];		/* ELF "magic number" */
+  Elf64_SHalf e_type;
+  Elf64_Half e_machine;
+  __s32 e_version;
+  Elf64_Addr e_entry;		/* Entry point virtual address */
+  Elf64_Off e_phoff;		/* Program header table file offset */
+  Elf64_Off e_shoff;		/* Section header table file offset */
+  __s32 e_flags;
+  Elf64_SHalf e_ehsize;
+  Elf64_SHalf e_phentsize;
+  Elf64_SHalf e_phnum;
+  Elf64_SHalf e_shentsize;
+  Elf64_SHalf e_shnum;
+  Elf64_SHalf e_shstrndx;
+} Elf64_Ehdr;
+
+/* These constants define the permissions on sections in the program
+   header, p_flags. */
+#define PF_R		0x4
+#define PF_W		0x2
+#define PF_X		0x1
+
+typedef struct elf32_phdr{
+  Elf32_Word	p_type;
+  Elf32_Off	p_offset;
+  Elf32_Addr	p_vaddr;
+  Elf32_Addr	p_paddr;
+  Elf32_Word	p_filesz;
+  Elf32_Word	p_memsz;
+  Elf32_Word	p_flags;
+  Elf32_Word	p_align;
+} Elf32_Phdr;
+
+typedef struct elf64_phdr {
+  __s32 p_type;
+  __s32 p_flags;
+  Elf64_Off p_offset;		/* Segment file offset */
+  Elf64_Addr p_vaddr;		/* Segment virtual address */
+  Elf64_Addr p_paddr;		/* Segment physical address */
+  Elf64_Word p_filesz;		/* Segment size in file */
+  Elf64_Word p_memsz;		/* Segment size in memory */
+  Elf64_Word p_align;		/* Segment alignment, file & memory */
+} Elf64_Phdr;
+
+/* sh_type */
+#define SHT_NULL	0
+#define SHT_PROGBITS	1
+#define SHT_SYMTAB	2
+#define SHT_STRTAB	3
+#define SHT_RELA	4
+#define SHT_HASH	5
+#define SHT_DYNAMIC	6
+#define SHT_NOTE	7
+#define SHT_NOBITS	8
+#define SHT_REL		9
+#define SHT_SHLIB	10
+#define SHT_DYNSYM	11
+#define SHT_NUM		12
+#define SHT_LOPROC	0x70000000
+#define SHT_HIPROC	0x7fffffff
+#define SHT_LOUSER	0x80000000
+#define SHT_HIUSER	0xffffffff
+
+/* sh_flags */
+#define SHF_WRITE	0x1
+#define SHF_ALLOC	0x2
+#define SHF_EXECINSTR	0x4
+#define SHF_MASKPROC	0xf0000000
+
+/* special section indexes */
+#define SHN_UNDEF	0
+#define SHN_LORESERVE	0xff00
+#define SHN_LOPROC	0xff00
+#define SHN_HIPROC	0xff1f
+#define SHN_ABS		0xfff1
+#define SHN_COMMON	0xfff2
+#define SHN_HIRESERVE	0xffff
+ 
+typedef struct {
+  Elf32_Word	sh_name;
+  Elf32_Word	sh_type;
+  Elf32_Word	sh_flags;
+  Elf32_Addr	sh_addr;
+  Elf32_Off	sh_offset;
+  Elf32_Word	sh_size;
+  Elf32_Word	sh_link;
+  Elf32_Word	sh_info;
+  Elf32_Word	sh_addralign;
+  Elf32_Word	sh_entsize;
+} Elf32_Shdr;
+
+typedef struct elf64_shdr {
+  Elf32_Word sh_name;		/* Section name, index in string tbl (yes Elf32) */
+  Elf32_Word sh_type;		/* Type of section (yes Elf32) */
+  Elf64_Word sh_flags;		/* Miscellaneous section attributes */
+  Elf64_Addr sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off sh_offset;		/* Section file offset */
+  Elf64_Word sh_size;		/* Size of section in bytes */
+  Elf32_Word sh_link;		/* Index of another section (yes Elf32) */
+  Elf32_Word sh_info;		/* Additional section information (yes Elf32) */
+  Elf64_Word sh_addralign;	/* Section alignment */
+  Elf64_Word sh_entsize;	/* Entry size if section holds table */
+} Elf64_Shdr;
+
+#define	EI_MAG0		0		/* e_ident[] indexes */
+#define	EI_MAG1		1
+#define	EI_MAG2		2
+#define	EI_MAG3		3
+#define	EI_CLASS	4
+#define	EI_DATA		5
+#define	EI_VERSION	6
+#define	EI_PAD		7
+
+#define	ELFMAG0		0x7f		/* EI_MAG */
+#define	ELFMAG1		'E'
+#define	ELFMAG2		'L'
+#define	ELFMAG3		'F'
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define	ELFCLASSNONE	0		/* EI_CLASS */
+#define	ELFCLASS32	1
+#define	ELFCLASS64	2
+#define	ELFCLASSNUM	3
+
+#define ELFDATANONE	0		/* e_ident[EI_DATA] */
+#define ELFDATA2LSB	1
+#define ELFDATA2MSB	2
+
+#define EV_NONE		0		/* e_version, EI_VERSION */
+#define EV_CURRENT	1
+#define EV_NUM		2
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS	1
+#define NT_PRFPREG	2
+#define NT_PRPSINFO	3
+#define NT_TASKSTRUCT	4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf32_note {
+  Elf32_Word	n_namesz;	/* Name size */
+  Elf32_Word	n_descsz;	/* Content size */
+  Elf32_Word	n_type;		/* Content type */
+} Elf32_Nhdr;
+
+/* Note header in a PT_NOTE section */
+/*
+ * For now we use the 32 bit version of the structure until we figure
+ * out whether we need anything better.  Note - on the Alpha, "unsigned int"
+ * is only 32 bits.
+ */
+typedef struct elf64_note {
+  Elf32_Word n_namesz;	/* Name size */
+  Elf32_Word n_descsz;	/* Content size */
+  Elf32_Word n_type;	/* Content type */
+} Elf64_Nhdr;
+
+#if ELF_CLASS == ELFCLASS32
+
+extern Elf32_Dyn _DYNAMIC [];
+#define elfhdr		elf32_hdr
+#define elf_phdr	elf32_phdr
+#define elf_note	elf32_note
+
+#else
+
+extern Elf64_Dyn _DYNAMIC [];
+#define elfhdr		elf64_hdr
+#define elf_phdr	elf64_phdr
+#define elf_note	elf64_note
+
+#endif
+
+
+#endif /* _LINUX_ELF_H */

Added: trunk/miboot/src/extract_dev_tree.c
===================================================================
--- trunk/miboot/src/extract_dev_tree.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/extract_dev_tree.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,280 @@
+#include <Types.h>
+#include <Quickdraw.h>
+#include <Devices.h>
+
+#include "uLibc.h"
+
+#include "extract_dev_tree.h"
+#include "debug_text.h"
+
+extern dt_context*	dct;
+
+// Globals
+int device_tree_skip_macos			= 1;
+int device_tree_max_prop_length		= 1024;
+
+// Statics
+static RegEntryID					gEntryID;
+static struct device_node*			gAllNodes;
+static struct device_node**			gAllNextP;
+static Ptr							gRegistryBase;
+
+static char*						gCurRegPath;
+
+// Prototypes
+static Ptr				inspect_node( 	struct device_node *dad, Ptr where );
+static unsigned char *	get_property( 	struct device_node *np, const char *name, unsigned long *lenp);
+static void				relocate_node(	struct device_node *np);
+
+// Macros
+#define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
+#define RELOC(x) ((x) ? (((Ptr)(x)) - gRegistryBase) : 0)
+
+// Exported copy_device_tree routine
+OSStatus
+copy_device_tree(Ptr where, unsigned long *size, unsigned long *outMainDispOffset)
+{
+	OSStatus		err;
+	Boolean			done = false;
+	Ptr				end;
+	GDHandle		mainDisplay;
+	AuxDCEHandle	mainDispDCE;
+	
+	/// By default, we don't know which one is the main display
+	*outMainDispOffset = 0;
+	
+	// We get the device control entry of the main display
+	mainDisplay = GetMainDevice();
+	mainDispDCE = (AuxDCEHandle)GetDCtlEntry((**mainDisplay).gdRefNum);
+	
+	// We get the root of the device tree inside the registry
+	err = RegistryEntryIDInit(&gEntryID);
+	if (err == noErr)
+		err = RegistryCStrEntryLookup(NULL, "Devices:device-tree", &gEntryID);
+	if (err != noErr)
+		return err;
+
+	if ((err == noErr) && !done) {
+		struct device_node*	node;
+		struct device_node*	next_node;
+		
+		// Iterate the registry & copy everything
+		gCurRegPath = NULL;		
+		gRegistryBase = where;
+		*((long *)where) = 0;
+		where += 4;
+		gAllNextP = &gAllNodes;
+		end = inspect_node(NULL, where);
+		*gAllNextP = 0;
+		*size = end - where + 4;
+// -- This one gives an error with Spotlight. I still have to check if it's a real
+//    error or not, but in the meantime, let's disable it.
+//		RegistryEntryIDDispose(&gEntryID);
+		
+		// Now, relocate it
+		node = gAllNodes;
+		while(node) {
+			unsigned char*	did;
+			unsigned long	didLength;
+			
+			// Get next node pointer before it is relocated
+			next_node = node->allnext;
+			
+			// Check if this node is a display device and contains the magic "did" property
+			if (strcmp(node->type, "display") == 0) {
+				did = get_property(node, "did", &didLength);
+				if (did && didLength == sizeof(unsigned long))
+					if (*((unsigned long *)did) == (**mainDispDCE).dCtlSlot)
+						*outMainDispOffset = (unsigned long)RELOC(node);
+			}	
+			
+			// Relocate the node		
+			relocate_node(node);
+			
+			// Go to next node
+			node = next_node;
+		}
+	} else
+		*size = 0;
+	
+	return err;
+}
+
+// Internel inspect_node recursive routine
+Ptr
+inspect_node( struct device_node *dad, Ptr where )
+{
+	OSStatus			err = noErr;
+//	unsigned long		l;
+	struct device_node	*np;
+	struct property		*pp, **prev_propp;
+	RegPropertyIter		propIter;
+	Boolean				done = false;
+	RegEntryID			me;
+	RegEntryIter		cookie;
+	char*				saveRegPath = gCurRegPath;
+
+	np = ( struct device_node * ) where;
+	where += sizeof( struct device_node );
+	memset(np, 0, sizeof(struct device_node));
+	
+//	np->node = node;
+	*gAllNextP = np;
+	gAllNextP = &np->allnext;
+	np->parent = dad;
+	if ( dad )
+	{
+		/* we temporarily use the `next' field as `last_child'. */
+		if (dad->next == 0)
+			dad->child = np;
+		else
+			dad->next->sibling = np;
+		dad->next = np;
+	}
+
+	/* get and store all properties */
+	prev_propp = &np->properties;
+	
+	err = RegistryPropertyIterateCreate( &gEntryID, &propIter );
+	
+	for (;;) {
+		pp = (struct property *) where;
+		pp->name = ( char * )( pp + 1 );
+		
+		err = RegistryPropertyIterate( &propIter, (RegPropertyName *)pp->name, &done);
+		if ( err || done )
+			break;
+		
+		// Skip MacOS driver property
+		if (device_tree_skip_macos && (strcmp(pp->name, "driver,AAPL,MacOS,PowerPC") == 0))
+			continue;
+
+		err = RegistryPropertyGetSize( &gEntryID, pp->name, ( unsigned long * )( &pp->length ) );
+		if (err != noErr)
+			continue;
+	
+		// Should not happen, but...
+		if (pp->length < 0)
+			continue;
+		
+		// Skip too large properties
+		if (device_tree_max_prop_length && (pp->length > device_tree_max_prop_length))
+			continue;
+
+		where = ( Ptr )ALIGN( ( unsigned long )pp->name + strlen( pp->name ) + 1 );
+		pp->value = ( unsigned char * ) where;
+		pp->length = -1;
+		err = RegistryPropertyGet( &gEntryID, pp->name, pp->value, ( unsigned long * )( &pp->length ) );
+		where = ( Ptr )ALIGN( ( unsigned long ) where + pp->length );
+
+		*prev_propp = pp;
+		prev_propp = &pp->next;
+	}
+	
+	done = false;
+	err = RegistryPropertyIterateDispose( &propIter );
+	*prev_propp = 0;
+
+	np->name = ( char * )get_property(np, "name", 0);
+	np->type = ( char * )get_property(np, "device_type", 0);
+
+	/* get the node's full name */
+	np->full_name = ( char * ) where;
+	if (gCurRegPath == NULL)
+		strcpy(np->full_name, "/");
+	else
+	{
+		strcpy(np->full_name, gCurRegPath);
+		if (strlen(gCurRegPath) > 1)
+			strcat(np->full_name, "/");
+		strcat(np->full_name, np->name);
+	}
+	gCurRegPath = np->full_name;
+//	dt_printf(dct, "%s\n", np->full_name);
+	where = ( Ptr )ALIGN( ( unsigned long ) where + strlen(np->full_name) + 1 );
+
+	/* Backup entry to me */
+	err = RegistryEntryIDInit(&me);
+	if (err != noErr)
+		return where;
+	
+	err = RegistryEntryIDCopy(&gEntryID, &me);
+	if (err != noErr)
+		return where;
+
+	/* Iterate child nodes */
+	err = RegistryEntryIterateCreate(&cookie);
+	if (err == noErr)
+		err = RegistryEntryIterateSet(&cookie, &gEntryID);
+	if (err == noErr)
+	{
+		err = RegistryEntryIterate( &cookie, kRegIterChildren, &gEntryID, &done);
+
+		while ((err == noErr) && !done)
+		{
+			where = inspect_node( np, where );
+			
+			err = RegistryEntryIterate( &cookie, kRegIterContinue, &gEntryID, &done );
+		}
+
+		RegistryEntryIterateDispose(&cookie);
+	}
+	
+	// we got done, so we must reset the gEntryID
+	err = RegistryEntryIDCopy(&me, &gEntryID);
+	if (err != noErr)
+		return where;
+
+	RegistryEntryIDDispose(&me);
+	
+	gCurRegPath = saveRegPath;
+	
+	return where;
+}
+
+unsigned char *
+get_property( struct device_node *np, const char *name, unsigned long *lenp)
+{
+	struct property *pp;
+
+	for ( pp = np->properties; pp != 0; pp = pp->next )
+		if ( strcmp( pp->name, (char *)name ) == 0 ) {
+			if ( lenp != 0 )
+				*lenp = pp->length;
+			return pp->value;
+		}
+	return nil;
+}
+
+void
+relocate_node(struct device_node *np)
+{
+	struct property*	prop;
+	struct property*	prop_next;
+	
+	prop = np->properties;
+	
+	np->name		= (char *)RELOC(np->name);
+	np->type		= (char *)RELOC(np->type);
+	np->node		= NULL;
+	np->addrs		= NULL;
+	np->full_name	= (char *)RELOC(np->full_name);
+	np->properties	= (struct property *)RELOC(np->properties);
+	np->parent		= (struct device_node *)RELOC(np->parent);
+	np->child		= (struct device_node *)RELOC(np->child);
+	np->sibling		= (struct device_node *)RELOC(np->sibling);
+	np->next		= (struct device_node *)RELOC(np->next);
+	np->allnext		= (struct device_node *)RELOC(np->allnext);
+	
+	while(prop)
+	{
+		prop_next = prop->next;
+		
+		prop->name	= (char *)RELOC(prop->name);
+		prop->value	= (unsigned char *)RELOC(prop->value);
+		prop->next	= (struct property *)RELOC(prop->next);
+		
+		prop = prop_next;
+	}
+}
+

Added: trunk/miboot/src/extract_dev_tree.h
===================================================================
--- trunk/miboot/src/extract_dev_tree.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/extract_dev_tree.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,73 @@
+#ifndef __DEVICETREE_H__
+#define __DEVICETREE_H__
+
+#include <NameRegistry.h>
+
+/* Structures that defines our copy of the Name Registry. This maps
+   exactly linux internal representation of the tree
+ */
+
+/* All this requires PowerPC alignement */
+#pragma options align=power
+
+typedef void *phandle;
+typedef void *ihandle;
+
+struct address_range {
+	unsigned int space;
+	unsigned int address;
+	unsigned int size;
+};
+
+struct interrupt_info {
+	int	line;
+	int	sense;		/* +ve/-ve logic, edge or level, etc. */
+};
+
+struct reg_property {
+	unsigned int address;
+	unsigned int size;
+};
+
+struct translation_property {
+	unsigned int virt;
+	unsigned int size;
+	unsigned int phys;
+	unsigned int flags;
+};
+
+struct property {
+	char	*name;
+	int	length;
+	unsigned char *value;
+	struct property *next;
+};
+
+struct device_node
+{
+	char	*name;					// To be remapped
+	char	*type;					// To be remapped
+	phandle	node;					// Nothing interesting here
+	int	n_addrs;					// Not initialised here
+	struct	address_range *addrs;	// Not initialised here
+	int	n_intrs;					// Not initialised here
+	struct	interrupt_info *intrs;	// Not initialised here
+	char	*full_name;				// To be remapped
+	struct	property *properties;	// To be remapped
+	struct	device_node *parent;	// To be remapped
+	struct	device_node *child;		// To be remapped
+	struct	device_node *sibling;	// To be remapped
+	struct	device_node *next;		// To be remapped (next device of same type)
+	struct	device_node *allnext;	// To be remapped (next in list of all nodes)
+};
+
+// Prototypes of exported functions
+extern OSStatus			copy_device_tree(Ptr where, unsigned long *size, unsigned long *outMainDispOffset);
+
+// Exported globals (options)
+extern int				device_tree_skip_macos;			// Skip MacOS drivers
+extern int				device_tree_max_prop_length;	// Max copied property length
+
+#pragma options align=reset
+
+#endif

Added: trunk/miboot/src/linux_type_defs.h
===================================================================
--- trunk/miboot/src/linux_type_defs.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/linux_type_defs.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,16 @@
+#ifndef __LINUX_TYPE_DEFS_H__
+#define __LINUX_TYPE_DEFS_H__
+
+/* Some linux base types. */
+typedef signed		char		__s8;
+typedef unsigned	char		__u8;
+typedef signed		short		__s16;
+typedef unsigned	short		__u16;
+typedef signed		long		__s32;
+typedef unsigned	long		__u32;
+typedef signed		long long	__s64;
+typedef unsigned	long long	__u64;
+
+
+
+#endif

Added: trunk/miboot/src/miBoot_boot2.S
===================================================================
--- trunk/miboot/src/miBoot_boot2.S	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/miBoot_boot2.S	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,137 @@
+#include <asm/MacErrors.h>
+#include <asm/Traps.h>
+
+#define RELOC		0
+#define TEST_PAINT	0
+
+/* Low memory globals */
+#define	kLM_SysZone		0x2a6
+#define	kLM_ApplZone	0x2aa
+#define kLM_TheZone		0x118
+#define kLM_BootMask	0xb0e
+#define kLM_BootDrive	0x210
+#define kLM_CurrentA5	0x904
+#define kLM_BufPtr		0x10c
+
+/* Increase system heap by this number of bytes */
+#define kSysZoneIncrease	0x200000 /* We ask for 2Mb */
+
+/*
+ * void start(void);
+ */
+	.text
+	.align 2
+	.globl start
+start:
+	/* First, the boot block code will have removed it's own
+	   return address from the stack, we recover it */
+		subq.l		#4, %sp
+		
+#if TEST_PAINT
+		jsr			%pc@(test_paint)
+#endif
+		
+#if RELOC
+	/* We copy ourselves on the stack */
+		movea.l		%a3,%a0
+		_GetHandleSize
+		lea      	real_entry,%a0
+		lea			start,%a1
+		suba.l		%a0,%a1
+		add.l		%a1,%d0
+		suba.l		%d0,%sp
+		movea.l		%sp,%a1
+		_BlockMove
+		jmp			(%a1)
+real_entry:	
+		move.l		%a3,-(%sp)
+		_ReleaseResource
+		move.l		%sp, 0x908	/* CurStackBase */
+#endif
+
+	/* This is in MacOS ... */
+		clr.l		0xa8c		/* RestProc */
+
+	/* We backup any register we'll be using */
+		move.l		%a2, -(%sp)
+		move.l		%a3, -(%sp)
+		
+	/* We check if the Application heap and System heap are the
+	   same. If they are not, then we move the application base
+	   in order to increase the system zone size
+	 */
+		movea.l		kLM_SysZone, %a2
+		cmpa.l		kLM_ApplZone, %a2
+		beq			same_zone
+		movea.l		(%a2), %a0
+		adda.l		#kSysZoneIncrease, %a0
+		_SetAppBase
+same_zone:
+		
+	/* Set the current zone to be the system zone */
+		move.l		%a2, kLM_TheZone
+	
+#if !RELOC
+	/* Detach ourselves (we should already be locked) */
+		move.l		%a3, -(%sp)
+		_DetachResource
+#endif
+	
+	/* Load the second code resource */
+		subq.l		#4, %sp
+		pea			0x626f6f74 /* 'boot' */
+		move.w		#3, -(%sp)
+		_GetResource
+		move.l		(%sp)+, %a2
+		cmpa.l		#0, %a2
+		beq			load_error
+	
+	/* Detach, move high and lock the resource. We don't use HLockHi, may not
+	   be in ROM */
+		move.l		%a2, -(%sp)
+		_DetachResource
+		movea.l		%a2, %a0
+		_MoveHHi
+		movea.l		%a2, %a0
+		_HLock
+	
+	/* Call the resource' code */
+		move.l		(%a2), %a0
+		move.l		kLM_BufPtr, -(%sp)
+		move.l		kLM_CurrentA5, -(%sp)
+		move.l		%a5, -(%sp)
+		jsr			(%a0)
+		move.l		(%sp)+, %a5
+		move.l		(%sp)+, kLM_CurrentA5
+		move.l		(%sp)+, kLM_BufPtr
+		
+	/* We got out of the booter, we must tell MacOS not to try booting
+	   from this partition */
+		move.w		kLM_BootMask, %d0
+		move.w		kLM_BootDrive, %d1
+		bclr		%d1, %d0
+		move.w		%d0, kLM_BootMask
+		
+	/* Get rid of the boot resource and unlock myself*/
+		movea.l		%a2, %a0
+		_DisposeHandle
+#if !RELOC
+		movea.l		%a3, %a0
+		_HUnlock
+#endif
+	
+	/* result code */
+//		moveq		#dsBadStartupDisk, %d0
+//		moveq		#0, %d0
+		moveq		#dsOldSystem, %d0
+		_SysError
+			
+	/* Exit (restore registers and return) */
+exit:
+		movea.l		(%sp)+, %a3
+		movea.l		(%sp)+, %a2
+		rts
+
+load_error:	
+		moveq		#dsBadStartupDisk, %d0
+		bra.s		exit

Added: trunk/miboot/src/miBoot_boot3.c
===================================================================
--- trunk/miboot/src/miBoot_boot3.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/miBoot_boot3.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,249 @@
+#include <Types.h>
+#include <Memory.h>
+#include <Quickdraw.h>
+#include <Palettes.h>
+#include <Fonts.h>
+#include <Events.h>
+#include <Menus.h>
+#include <Errors.h>
+#include <Files.h>
+#include <Devices.h>
+#include <Windows.h>
+#include <Icons.h>
+#include <LowMem.h>
+#if defined(__MWERKS__)
+#include <A4Stuff.h>
+#endif
+
+#include "debug_text.h"
+#include "nr_wrapper.h"
+
+#define VERSION		"1.0d4"
+
+static void set_a5_world(void);
+static void test_paint(void);
+static void setup_debug_context(Boolean debug_visible);
+static void show_context(void);
+static void	setup_quickdraw(void);
+static void	close_quickdraw(void);
+static void draw_penguin(short whichPenguin);
+static void	load_boot4(void);
+static void	check_opt_keys(void);
+
+/* Globals */
+dt_context*	dct;
+QDGlobals	qd;
+GrafPtr		port;
+
+dt_context	g_dct;
+CGrafPort	g_grafport;
+Boolean		g_use_color = 1;
+Boolean		g_debug_visible = 0;
+
+#define kPenguinNormalID		128
+#define kPenguinRamDiskID		129
+#define kPenguinErrorID			130
+
+void start(void)
+{
+#if defined(__MWERKS__)
+	EnterCodeResource();
+#endif
+	
+	check_opt_keys();
+	setup_debug_context(g_debug_visible);
+	
+	dt_printf(dct, "Welcome to miBoot v" VERSION "\n\n");
+	
+	show_context();
+	
+	dt_printf(dct, "Setting up drawing environment...");
+	setup_quickdraw();
+	dt_printf(dct, "ok.\n");
+	dt_printf(dct, "Drawing penguin...");
+	draw_penguin(kPenguinNormalID);
+	dt_printf(dct, "ok.\n");
+
+	load_boot4();
+	
+	draw_penguin(kPenguinErrorID);
+	dt_printf(dct, "\nQuitting...\n");	
+	close_quickdraw();
+	
+#if defined(__MWERKS__)
+	ExitCodeResource();
+#endif
+}
+
+void
+load_boot4(void)
+{
+	Handle	rsrc = GetResource('boot', 4);
+	if (!rsrc) {
+		dt_printf(dct, "GetResource('boot', 4) error %d\n", ResError());
+		return;
+	}
+	DetachResource(rsrc);
+	MoveHHi(rsrc);
+	HLock(rsrc);
+	
+	((void (*)(dt_context*))(*rsrc))(dct);
+	
+	DisposeHandle(rsrc);
+}
+
+void
+draw_penguin(short whichPenguin)
+{
+	CIconHandle	icon;
+	Rect		bounds;
+	
+	icon = GetCIcon(whichPenguin);
+	if (!icon) {
+		dt_printf(dct, "Can't load penguin icon (ResErr: %d) !\n",
+			ResError());
+		return;
+	}
+
+	bounds.left = port->portRect.left + (port->portRect.right - port->portRect.left)/2 - 16;
+	bounds.top = port->portRect.top + (port->portRect.bottom - port->portRect.top)/2 - 16;
+	bounds.right = bounds.left + 32;
+	bounds.bottom = bounds.top + 32;
+	
+	FillRect(&bounds, &qd.gray);
+
+	PlotCIcon(&bounds, icon);
+	DisposeCIcon(icon);
+}
+
+#if defined(__GNUC__)
+void
+set_a5_world(void)
+{
+	register void *a5 asm ("%a5");
+
+	/* FIXME: %a0 seems dead */
+	__asm__ __volatile__ (
+		"lea		%0, %%a0\n\t"
+		"adda.l		%1, %%a0"
+	:
+	:	"o" (qd),
+		"i" ((size_t) &(((QDGlobals*) 0) -> thePort))
+	:	"%a0"
+	);
+
+	LMSetCurrentA5(a5);
+}
+#else
+asm void
+set_a5_world(void)
+{
+#define kLM_CurrentA5	0x904
+	lea		qd, a0
+	adda.l	#struct(QDGlobals.thePort), a0
+	move.l	a5, kLM_CurrentA5
+	rts
+}
+#endif
+
+void
+setup_quickdraw(void)
+{
+	set_a5_world();
+	InitGraf(&qd.thePort);
+	InitPalettes();
+	port = (GrafPtr)&g_grafport;
+	if (g_use_color)
+		OpenCPort(&g_grafport);
+	else
+		OpenPort(port);
+	SetPort(port);
+	PenNormal();
+}
+
+void
+close_quickdraw(void)
+{
+	if (g_use_color)
+		CloseCPort(&g_grafport);
+	else
+		ClosePort(port);
+}
+
+void
+setup_debug_context(Boolean debug_visible)
+{
+	GDHandle	hdl;
+	PixMapPtr	pm;
+	UInt32		x,y;
+	
+	hdl = LMGetMainDevice();
+	if (hdl == NULL || (**hdl).gdPMap == NULL)
+		return;
+	pm = *(**hdl).gdPMap;
+	if (pm->baseAddr == NULL)
+		return;
+	
+	dct = &g_dct;
+	
+	dct->base = (unsigned char *)pm->baseAddr;
+	dct->row_bytes = pm->rowBytes & 0x3fff;
+	dct->width = pm->bounds.right - pm->bounds.left;
+	dct->height = pm->bounds.bottom - pm->bounds.top;
+	dct->depth = pm->pixelSize;
+	dct->visible = debug_visible;
+	
+	if (dct->depth == 15)
+		dct->depth = 16;
+	
+	dct->base += pm->bounds.top * dct->row_bytes;
+	dct->base += pm->bounds.left * (dct->depth >> 3);
+	
+	dt_init(dct);
+}
+
+#if defined(__GNUC__)
+UInt32 read_sp(void)
+{
+	return (UInt32) __builtin_frame_address(0);
+}
+#else
+asm UInt32 read_sp(void)
+{
+	move.l	sp, d0
+	rts
+}
+#endif
+
+void
+show_context(void)
+{
+	dt_printf(dct, "SystemZone start : 0x%08lx\n", LMGetSysZone()->bkLim);
+	dt_printf(dct, "SystemZone free  : 0x%08lx\n", LMGetSysZone()->zcbFree);
+	dt_printf(dct, "CurrenZone start : 0x%08lx\n", LMGetTheZone()->bkLim);
+	dt_printf(dct, "CurrenZone free  : 0x%08lx\n", LMGetTheZone()->zcbFree);
+	dt_printf(dct, "ApplZone start   : 0x%08lx\n", LMGetApplZone()->bkLim);
+	dt_printf(dct, "ApplZone free    : 0x%08lx\n", LMGetApplZone()->zcbFree);
+	dt_printf(dct, "ApplLimit        : 0x%08lx\n", LMGetApplLimit());
+	dt_printf(dct, "CurStackBase     : 0x%08lx\n", LMGetCurStackBase());
+	dt_printf(dct, "BufPtr           : 0x%08lx\n", LMGetBufPtr());
+	dt_printf(dct, "MemTop           : 0x%08lx\n", LMGetMemTop());
+	dt_printf(dct, "-> limit         : 0x%08lx\n", ((UInt32)LMGetMemTop()/2 + 1024));
+	dt_printf(dct, "sp               : 0x%08lx\n", read_sp());
+	dt_printf(dct, "-> free          : 0x%08lx\n", read_sp() - (UInt32)LMGetApplLimit());
+}
+
+static check_one_key(KeyMap map, UInt8 key_code)
+{
+	return ((((UInt8 *)map)[key_code >> 3] >> (key_code & 7)) & 1);
+}
+
+void
+check_opt_keys(void)
+{
+	KeyMap	keys;
+	
+	GetKeys(keys);
+	if (check_one_key(keys, 0x3a))
+		g_debug_visible = 1;
+}

Added: trunk/miboot/src/miBoot_boot4.c
===================================================================
--- trunk/miboot/src/miBoot_boot4.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/miBoot_boot4.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,783 @@
+#include <Types.h>
+#include <Memory.h>
+#include <Errors.h>
+#include <Files.h>
+#include <Devices.h>
+#include <TextUtils.h>
+#include <LowMem.h>
+#if defined(__MWERKS__)
+#include <A4Stuff.h>
+#endif
+#include <Resources.h>
+
+#include "uLibc.h"
+#include "debug_text.h"
+#include "nr_wrapper.h"
+#include "zlib.h"
+#include "elf_loader_defs.h"
+#include "extract_dev_tree.h"
+#include "bootx.h"
+#include "LowLevelBoot.h"
+#include "rs6000.h"
+
+#define DEBUG	0
+
+static Ptr 		load_kernel(Str255 file_name, UInt32 *out_size);
+static OSErr	gunzip(void *dst, int dstlen, unsigned char *src, int *lenp);
+static OSErr	check_elf_kernel(Ptr kernel, UInt32 *out_offset, UInt32 *out_real_size, UInt32 *out_entry);
+static void		do_boot(UInt8* gz_kernel, UInt32 gz_kernel_size, int flags,
+					char *kernel_args, UInt8* ramdisk, UInt32 ramdisk_size);
+static OSErr	build_pci_device_tree(Ptr* outDevTree, UInt32 *outDevTreeSize, UInt32 *outDispRegOff);
+static OSErr	make_resident(void* ptr, unsigned long size, Boolean contiguous);
+static void*	load_bootstrap(long mapSize, UInt32** outMapBegin,UInt32 *outTotalSize);
+static int		check_kernel_format(int *out_flags, UInt8 **kern, UInt32 *kern_size,
+					UInt8 **out_rd, UInt32 *out_rds);
+
+#define get_16be(x)	(*(unsigned short *)(x))
+#define get_32be(x)	(*(unsigned *)(x))
+
+UInt8*	get_physical(void* ptr);
+
+/* Globals */
+dt_context*	dct = NULL;
+UInt32 g_page_size = 4096;
+
+#define KERNEL_ELF		0x01
+#define KERNEL_XCOFF	0x02
+#define KERNEL_GZIPPED	0x04
+
+void start(dt_context *input_context)
+{
+	Ptr	k;
+	UInt32 ks;
+	Handle cmd;
+	Str63 kern_name;
+	
+#if defined(__MWERKS__)
+	EnterCodeResource();
+#endif
+
+	dct = input_context;
+	dt_printf(dct, "\nLow-level entry...\n");
+	
+	dt_printf(dct, "Initialize Name Registry wrappers...\n");
+	init_nr_wrappers();
+
+	dt_printf(dct, "Loading kernel...\n");
+	GetIndString(kern_name, 128, 1);
+	k = load_kernel(kern_name, &ks);
+	if (k) {
+		int		flags;
+		UInt8	*rd, *kern;
+		UInt32	rds;
+		
+		kern = (UInt8 *)k;
+		if (check_kernel_format(&flags, &kern, &ks, &rd, &rds) != noErr) {
+			dt_printf(dct, "Unknown kernel format\n");
+			DisposePtr(k);
+			goto fail;
+		}
+		cmd = GetResource('CMDL', 128);
+		if (cmd) {
+			DetachResource(cmd);
+			HLock(cmd);
+		}
+		do_boot(kern, ks, flags, cmd ? *cmd : NULL, rd, rds);
+		if (cmd)
+			DisposeHandle(cmd);
+		DisposePtr(k);
+	}
+
+fail:
+	dt_printf(dct, "Exiting...\n");
+	dispose_nr_wrappers();
+	
+#if defined(__MWERKS__)
+	ExitCodeResource();
+#endif
+}
+
+Ptr
+load_kernel(Str255 file_name, UInt32 *out_size)
+{
+	HParamBlockRec	pb;
+	short			rn;
+	Ptr				buffer;
+	SInt32			file_size;
+	OSErr			err;
+	
+	buffer = NULL;
+	
+	pb.fileParam.ioCompletion = NULL;
+	pb.fileParam.ioNamePtr = file_name;
+	pb.fileParam.ioVRefNum = -1;
+	pb.fileParam.ioDirID = 2;
+	pb.fileParam.filler1 = fsRdPerm;
+	err = PBHOpenSync(&pb);
+	if (err != noErr) {
+		dt_printf(dct, "open error %d!\n", err);
+		return NULL;
+	}
+	rn = pb.ioParam.ioRefNum;
+
+	err = GetEOF(rn, &file_size);
+	if ((err != noErr) || file_size == 0) {
+		dt_printf(dct, "Can't get eof ! (%d)\n", err);
+		goto bail;
+	}
+	
+	*out_size = file_size;
+
+	buffer = NewPtr(file_size);
+	if (!buffer) {
+		dt_printf(dct, "failed\n");
+		goto bail;
+	}
+
+	dt_printf(dct, "Reading %ld Kbytes at 0x%lx...\n", file_size/1024, buffer);
+	pb.ioParam.ioCompletion = NULL;
+	pb.ioParam.ioRefNum = rn;
+	pb.ioParam.ioBuffer = buffer;
+	pb.ioParam.ioReqCount = file_size;
+	pb.ioParam.ioPosMode = fsFromStart;
+	pb.ioParam.ioPosOffset = 0;
+	pb.ioParam.ioMisc = 0;
+	err = PBReadSync((ParmBlkPtr)&pb);
+	if ((err != noErr) && (err != eofErr)) {
+		dt_printf(dct, "read error %d !\n", err);
+		DisposePtr(buffer);
+		buffer = NULL;
+		goto bail;
+	}
+	FSClose(rn);
+
+bail:	
+	return buffer;
+}
+
+static void *
+zalloc(void *x, unsigned items, unsigned size)
+{
+  	Ptr	p = NewPtr(size * items);
+  	
+  	if (!p)
+  		dt_printf(dct, "zalloc(%d bytes) failed (err: %d) !",
+  			(size*items), MemError());
+  	
+  	return p;
+}
+
+static void
+zfree(void *x, void *addr, unsigned nb)
+{
+	if (addr)
+		DisposePtr(addr);
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+OSErr
+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) {
+		dt_printf(dct, "bad gzipped data\n");
+		return -1;
+    }
+    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) {
+		dt_printf(dct, "gunzip: ran out of data in header\n");
+		return -1;
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+		dt_printf(dct, "inflateInit2 returned %d\n", r);
+		return -1;
+    }
+    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) {
+		dt_printf(dct, "inflate returned %d\n", r);
+		return -1;
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+   	
+   	return noErr;
+}
+
+#define NAME_REGISTRY_MAX_SIZE		(200UL * 1024UL)			// 200Kb: Size pre-allocated for holding name registry
+#define BOOT_KERNEL_STACK_SIZE		65536						// initial stack
+
+#define PAGE_ALIGN(x)	((((UInt32)(x)) + g_page_size - 1) & (-g_page_size))
+#define LINE_ALIGN(x)	((((UInt32)(x)) + 32 - 1) & (-32))
+#define BI_OFFSET(x)	(offsets[x] - offsets[offset_bootinfo])
+	
+/* Indexes in offset array */
+enum
+{
+	offset_kernel = 0,	/* kernel itself, offset 0 */
+	offset_stack,		/* boot stack */
+	offset_bootinfo,	/* boot_info */
+	offset_arguments,	/* args line */
+	offset_color_map,	/* colormap setup by bootx */
+	offset_device_tree,	/* device tree */
+	offset_ramdisk,		/* optional ramdisk */
+	offset_unmangler,	/* unmangler (may be moved higher) */
+	offset_count
+};
+
+void
+do_boot(UInt8* gz_kernel, UInt32 gz_kernel_size, int flags,
+	char *kernel_args, UInt8* ramdisk, UInt32 ramdisk_size)
+{
+	Ptr		 		saveBufPtr = LMGetBufPtr();
+	Ptr				curBufPtr;
+	OSStatus		err;
+	UInt32			offsets[offset_count];
+	Ptr				main_base;
+	UInt32			total_size;
+	Ptr				dev_tree;
+	UInt32			dev_tree_size;
+	UInt32			dev_tree_disp_off;
+	UInt32			real_kern_size;
+	int				uncomp_kern_size;
+	UInt32			kern_entry;
+	UInt32			kern_offset;
+	Ptr				kernel_loc;
+	void*			strap_entry;
+	UInt32			strap_phys_entry, strap_dest;
+	UInt32			boot_map_addr, strap_size;
+	UInt32			prec, args_len;
+	UInt32*			map_loc;
+	UInt32			main_base_phys;
+	Handle			boot_resource_PPC;
+	void*			boot_glue_PPC;
+	boot_infos_t*	bi;
+	static PPCRegisterList	regList;	
+	
+	/* Build the copy of the device tree */
+	dt_printf(dct, "Copying device tree...\n");
+	err = build_pci_device_tree(&dev_tree, &dev_tree_size, &dev_tree_disp_off);
+	if (err != noErr) {
+		dt_printf(dct, "build_pci_device_tree returned error %d\n", err);
+		return;
+	}
+	dt_printf(dct, "Device tree is %d bytes at 0x%lx\n", dev_tree_size, dev_tree);
+
+	/* We uncompress the kernel at bufPtr - 4M (should be enough). We need this
+	   in order to find out the uncompressed size
+	 */
+	LMSetBufPtr(curBufPtr = (saveBufPtr - 0x400000));
+	uncomp_kern_size = gz_kernel_size;
+	if (flags & KERNEL_GZIPPED) {
+		dt_printf(dct, "Unzipping kernel (@0x%lx)... ", gz_kernel);
+		err = gunzip(curBufPtr, 0x400000, (unsigned char *)gz_kernel, &uncomp_kern_size);
+		if (err != noErr) {
+			dt_printf(dct, "failed !\n");
+			DisposePtr(dev_tree);
+			goto fail;
+		}
+		dt_printf(dct, "%ld KByte.\n", uncomp_kern_size/1024);
+	} else
+		memcpy(curBufPtr, gz_kernel, uncomp_kern_size);
+	kernel_loc = curBufPtr;
+	
+	/* Now that the kernel is uncompressed, we can "check" it and get it's real
+	   size, entry point, etc...
+	 */
+	real_kern_size = uncomp_kern_size;
+	if (flags & KERNEL_ELF) {
+		if (check_elf_kernel(kernel_loc, &kern_offset, &real_kern_size, &kern_entry) != noErr) {
+			dt_printf(dct, "check_elf_kernel failed !\n");
+			DisposePtr(dev_tree);
+			goto fail;
+		}
+	} else {
+		/* I've not been able to figure out where to find the memory footprint for
+		   the kernel in this case.
+		   We leave an arbitrary size of 2Mb after the kernel, this should be
+		   enough for all cases, but it's ugly :-(
+		   Also, we should handle the case where we are not dealing with an XCOFF entry
+		   (Cort will change the entrypoint).
+		 */
+		if (((UInt32 *)(kernel_loc))[2] != 0)
+			dt_printf(dct, "strange xcoff descriptor\n");
+		kern_entry = *(UInt32 *)(kernel_loc);
+		dt_printf(dct, "xcoff entry: 0x%x, kern size: %ld KBytes\n",
+			kern_entry, real_kern_size/1024);
+		real_kern_size += 0x200000;
+		kern_offset = 0;
+	}
+	
+	/* We build the map of offsets. Note that unlike BootX, we don't build a map
+	   of the kernel. At this point, VM should not be initialised yet. We still have
+	   the theorical possibility that memory is fragmented, let's just hope it's not
+	   for now (may happen on Nubus machines and 68k).
+	 */
+	if (ramdisk == NULL)
+		ramdisk_size = 0;
+	if (kernel_args == NULL)
+		args_len = 0;
+	else
+		args_len = strlen(kernel_args)+1;
+	offsets[offset_kernel]		= 0;
+	offsets[offset_stack]		= prec = PAGE_ALIGN(real_kern_size);
+	offsets[offset_bootinfo]	= prec = PAGE_ALIGN(prec + BOOT_KERNEL_STACK_SIZE);
+	offsets[offset_arguments]	= prec = LINE_ALIGN(prec + sizeof(boot_infos_t));
+	offsets[offset_color_map]	= prec = LINE_ALIGN(prec + args_len);
+	offsets[offset_device_tree]	= prec = LINE_ALIGN(prec + BOOTX_COLORTABLE_SIZE);
+	offsets[offset_ramdisk]		= prec = PAGE_ALIGN(prec + dev_tree_size);
+	offsets[offset_unmangler]	= prec = PAGE_ALIGN(prec + ramdisk_size);
+	total_size = prec + g_page_size;
+	/* We do the final bufPtr allocation */
+	LMSetBufPtr(curBufPtr = (saveBufPtr - total_size - g_page_size));
+	main_base = (Ptr)PAGE_ALIGN(curBufPtr);
+	main_base_phys = (UInt32)get_physical(main_base);
+	memset(main_base + offsets[offset_stack], 0, BOOT_KERNEL_STACK_SIZE);
+	
+	dt_printf(dct, "Main load base: 0x%x\n", main_base);
+	
+	/* We move the kernel to it's final location */
+	memmove(main_base, kernel_loc + kern_offset, real_kern_size);
+	
+	/* We setup the boot-info stucture and fill it */
+	bi = (boot_infos_t *)(main_base + offsets[offset_bootinfo]);
+	memset(bi, 0, sizeof(boot_infos_t));
+	bi->version					= BOOT_INFO_VERSION;
+	bi->compatible_version		= BOOT_INFO_COMPATIBLE_VERSION;
+	bi->machineID				= 0; /* FIXME ! (check if Gestalt is impl.) */
+	bi->architecture			= BOOT_ARCH_PCI; /* FIXME ! */
+	bi->totalParamsSize			= BI_OFFSET(offset_unmangler);
+	if (kernel_args) {
+		bi->kernelParamsOffset	= BI_OFFSET(offset_arguments);
+		memcpy(main_base + offsets[offset_arguments], kernel_args, args_len);
+	} else
+		bi->kernelParamsOffset	= 0;
+
+	/* Make room for the colormap and store the offset. This offset will be used or cleared
+	   when the display device infos are really gathered by the low-level booter */
+	bi->dispDeviceColorsOffset	= BI_OFFSET(offset_color_map);
+
+	/* Copy in the device tree */
+	bi->deviceTreeOffset			= BI_OFFSET(offset_device_tree);
+	bi->deviceTreeSize				= dev_tree_size;
+	bi->dispDeviceRegEntryOffset	= dev_tree_disp_off;
+	memcpy(main_base + offsets[offset_device_tree], dev_tree, dev_tree_size);
+
+	/* Copy the ramdisk */
+	if (ramdisk_size) {
+		dt_printf(dct, "Copying ramdisk (0x%x Kbytes)\n", ramdisk_size/1024);
+		memcpy(main_base + offsets[offset_ramdisk], ramdisk, ramdisk_size);
+		bi->ramDisk				= BI_OFFSET(offset_ramdisk);
+		bi->ramDiskSize			= ramdisk_size;
+	}
+
+	/* Load the pre-strap code that shuts down known devices
+	   to prevent them from bus mastering to main memory
+	 */
+	boot_resource_PPC = Get1Resource('BSTP', 129);
+	if (!boot_resource_PPC) {
+		err = ResError();
+		dt_printf(dct, "failed to load pre-strap, err: %d\n",err);
+		DisposePtr(dev_tree);
+		return;
+	}
+	DetachResource(boot_resource_PPC);
+	HLock(boot_resource_PPC);
+
+	// the map size is multiplied by 2 to make room for "temp" copy
+	// operations that will be generated when source pages overlap
+	// destination. It's then multiplied by 12 which is the size of
+	// an entry in the copy-table.
+	// We use a small map of 1 entry for now to just copy the whole
+	// block down to 0.
+	strap_entry = load_bootstrap(2*12, &map_loc, &strap_size);
+	if (!strap_entry) {
+		DisposeHandle(boot_resource_PPC);
+		DisposePtr(dev_tree);
+		return;
+	}
+
+	// Make the boostrap resident and contiguous
+	err = make_resident(strap_entry, strap_size+g_page_size, true);
+	if (err != noErr) {
+		DisposeHandle(boot_resource_PPC);
+		DisposePtr(dev_tree);
+		return;
+	}
+	// The boostrap will move itself just after the kernel.
+	// We just make sure that source and dest don't overlap
+	// itself or one of the kernel pages
+	strap_size			= PAGE_ALIGN(strap_size);
+	strap_phys_entry	= (UInt32)get_physical(strap_entry);
+	strap_dest			= strap_phys_entry;
+	
+	if (strap_dest < offsets[offset_unmangler])
+		strap_dest = PAGE_ALIGN(offsets[offset_unmangler] + strap_size);
+	if ((strap_dest >= (main_base_phys - strap_size)) &&
+		(strap_dest < (main_base_phys + total_size)))
+		strap_dest = PAGE_ALIGN(main_base_phys + total_size);
+	if ((strap_dest >= (strap_phys_entry - strap_size)) &&
+		(strap_dest < (strap_phys_entry + strap_size)))
+		strap_dest = PAGE_ALIGN(strap_phys_entry + total_size);
+	
+	boot_map_addr = strap_dest + ((UInt32)map_loc - (UInt32)strap_entry);
+	
+	dt_printf(dct, "strap entry      : 0x%lx\n", strap_entry);
+	dt_printf(dct, "strap dest       : 0x%lx\n", strap_dest);
+	dt_printf(dct, "strap phys entry : 0x%lx\n", strap_phys_entry);
+	dt_printf(dct, "strap size       : 0x%lx\n", strap_size);
+
+	map_loc[0] = main_base_phys;
+	map_loc[1] = 0; /* g_load_base */
+	map_loc[2] = offsets[offset_unmangler];
+	map_loc[3] = 0;
+	map_loc[4] = 0;
+	map_loc[5] = 0;
+	
+	regList.PC		= (unsigned long)strap_entry;
+	regList.GPR[1]	= 0/*g_load_base*/ + offsets[offset_stack] + BOOT_KERNEL_STACK_SIZE - 512;	// The stack for the kernel entry
+	regList.GPR[2]	= 1;													// r2 flag must be set to 1 by BootX 
+	regList.GPR[3]	= 'BooX';												// r3 contains 'BooX' ($426F6F58)
+	regList.GPR[4]	= 0/*g_load_base*/ + offsets[offset_bootinfo];			// r4 contains the boot infos ptr
+	regList.GPR[5]	= 0; /*iMacHack;*/									// r5 NULL, replaced by low-bootsrap with map base of fb
+	regList.GPR[6]	= strap_phys_entry;										// r6 contains phys addr. of bootstrap
+	regList.GPR[7]	= strap_dest;											// r7 contains dest addr. of bootstrap
+	regList.GPR[8]	= strap_size;
+	regList.GPR[9]	= boot_map_addr;
+	regList.GPR[10]	= kern_entry + 0/* g_load_base*/ + offsets[offset_kernel];
+	regList.GPR[11]	= 0;
+
+	// -- Call the low-level PPC boot glue (returns a pointer to an UPP) --
+	//    this call will make sure the code fragment is prepared and returns a pointer
+	//    that can later be called by the 68k code
+#if defined(__GNUC__)
+	__asm__ __volatile__ (
+		"subq.w #4, %/sp\n\t"
+		"jsr %1@\n\t"
+		"move.l (%/sp)+, %0"
+	:	"=d" (boot_glue_PPC)
+	:	"a" (*boot_resource_PPC)
+	:	"%a0", "%a1", "%a2", "%d0", "%d1", "%d2"
+	);
+#else
+	boot_glue_PPC = ((pascal void*(*)(void))(*boot_resource_PPC))();
+#endif
+
+	low_boot(&regList, bi, boot_glue_PPC);
+	
+fail:
+	LMSetBufPtr(saveBufPtr);
+}
+
+OSErr
+build_pci_device_tree(Ptr* outDevTree, UInt32 *outDevTreeSize, UInt32 *outDispRegOff)
+{
+	Ptr				devTree;
+	OSErr			err;
+	
+	// First make a copy of the device tree.
+	devTree	= NewPtr(NAME_REGISTRY_MAX_SIZE);
+	if (devTree == NULL) {
+		err = MemError();
+		if (err == noErr) err = memFullErr;
+		dt_printf(dct, "Can't allocate room for name registry (%d)\n", err);
+		return err;
+	}
+	err = noErr;
+	
+	*outDevTreeSize = NAME_REGISTRY_MAX_SIZE;
+	err = copy_device_tree(devTree, outDevTreeSize, outDispRegOff);
+	if (err != noErr && (*outDevTreeSize > NAME_REGISTRY_MAX_SIZE)) {
+		dt_printf(dct, "Device tree overflow ! Your machine is probably crashed now.\n");
+		DisposePtr(devTree);		
+		return err;
+	} else if (err != noErr) {
+		dt_printf(dct, "Error %d while copying device tree !\n", err);
+		DisposePtr(devTree);		
+	}
+	
+	*outDevTree = devTree;
+	
+	return noErr;	
+}
+
+OSErr
+check_elf_kernel(Ptr kernel, UInt32 *out_offset, UInt32 *out_real_size, UInt32 *out_entry)
+{
+	OSErr		err;
+	long		nb;
+	int 		i;
+	Elf32_Ehdr	*e;
+	Elf32_Phdr	*p;
+	UInt32		total_file_size;
+	UInt32		offset, entry, load_loc;
+	UInt32		size, start;
+	
+	offset = entry = size =0;
+	total_file_size = *out_real_size;
+	e = (Elf32_Ehdr *)kernel;
+	
+	/* Check if it is an executable elf binary.
+	 */
+	err = -1;
+	if (!(e->e_ident[EI_MAG0] == ELFMAG0 && e->e_ident[EI_MAG1] == ELFMAG1 &&
+		  e->e_ident[EI_MAG2] == ELFMAG2 && e->e_ident[EI_MAG3] == ELFMAG3)) {
+		dt_printf(dct, "Kernel doesn't look like an ELF image !");
+		goto out;
+	}
+	if (e->e_ident[EI_CLASS] != ELFCLASS32
+		|| e->e_ident[EI_DATA] != ELFDATA2MSB) {
+		dt_printf(dct, "Kernel ELF image is wrong format (not PPC MSB 32) !");
+	    goto out;
+	}
+	
+	/* Check in the program header */
+	p = (Elf32_Phdr *)(kernel + e->e_phoff);
+
+#define ADDRMASK	0x0fffffff
+	size = 0;
+
+	/* Scan through the program header
+	 * HACK:  We must return the _memory size of the kernel image, not the
+	 *        file size (because we have to leave room before other boot
+	 *	  infos. This code works as a side effect of the fact that
+	 *	  we have one section and vaddr == p_paddr
+	 */
+	for (i = 0; i < e->e_phnum; ++i, ++p) {
+	    if (p->p_type != PT_LOAD || p->p_offset == 0)
+			continue;
+	    if (size == 0) {
+			offset = p->p_offset;
+			size = p->p_memsz; /*p->p_filesz*/;
+			load_loc = p->p_vaddr & ADDRMASK;
+			dt_printf(dct, "size (1) : 0x%x\n", size);
+	    } else {
+			size = p->p_offset + p->p_memsz - offset;
+			dt_printf(dct, "size (2) : 0x%x\n", size);
+		}
+	}
+	if (size == 0) {
+		dt_printf(dct, "Can't find a loadable segment in the kernel image !\n");
+		goto out;
+	}
+	entry = (UInt32)(e->e_entry & ADDRMASK) - load_loc;
+	
+	/* Fix coff entry */
+	start = *(UInt32 *)(kernel + offset + entry);
+    if ((start < load_loc) || (start >= (load_loc + size))
+		|| (((UInt32 *)(kernel + offset + entry))[2] != 0))
+		/* doesn't look like a procedure descriptor */
+		start = entry + load_loc;
+	entry = start - load_loc;
+	
+	dt_printf(dct, "k_real_size: %d bytes\n", size);
+	dt_printf(dct, "k_offset   : %d bytes\n", offset);
+	dt_printf(dct, "k_entry_off: %d bytes\n", entry);
+	*out_real_size = size;
+	*out_offset = offset;
+	*out_entry = entry;
+
+	return 0;
+ out:
+ 	return -1;
+}
+
+/* Get the physical address, if possible, of a pointer. Note that
+ * we fail silently since we _do_ fail sometimes, like for screen
+ * base address. In this case, we just return the original pointer
+ */
+UInt8*
+get_physical(void* ptr)
+{
+	LogicalToPhysicalTable	table;
+	unsigned long			count;
+	OSErr					err;
+	
+	table.logical.address	= ptr;
+	table.logical.count		= 1024;
+	count = sizeof( table ) / sizeof( MemoryBlock ) - 1;
+	
+	err = GetPhysical( &table, &count );
+	if ( err != noErr)
+		return ptr;
+	
+	return (UInt8 *)(table.physical[0].address);
+}
+
+/* Make a portion of memory resident. */
+OSErr
+make_resident(void* ptr, unsigned long size, Boolean contiguous)
+{
+	OSErr	err;
+	
+	if (size % g_page_size)
+		size = size + g_page_size - (size % g_page_size);
+
+	err = contiguous ? LockMemoryContiguous(ptr, size) : LockMemory(ptr, size);
+
+bail:
+	if (err != noErr)
+		dt_printf(dct, "LockMemory%s failed, err: %d\n",
+			contiguous ? "Contiguous" : "", err);
+	return err;
+}
+
+void *
+load_bootstrap(long mapSize, UInt32** outMapBegin,UInt32 *outTotalSize)
+{
+	Handle				krsrc;
+	OSErr				err;
+	CFragConnectionID	fragID;
+	Ptr					fragEntry, loc;
+	Str255				errStr;
+	UInt32				origSize, extOrigSize, newSize;
+	
+	krsrc = GetResource('BSTP', 128);
+	if (!krsrc) {
+		dt_printf(dct, "Can't load boostrap resource, err: %d\n",
+			ResError());
+		goto error;
+	}
+	DetachResource(krsrc);
+	HUnlock(krsrc);
+	origSize = GetHandleSize(krsrc);
+	extOrigSize  = origSize;
+	extOrigSize += 0x00000FFFUL;
+	extOrigSize &= 0xFFFFF000UL;
+	mapSize  += 0x00000FFFUL;
+	mapSize  &= 0xFFFFF000UL;
+	/* we add a page size since we'll align things */
+	newSize	  = extOrigSize + mapSize + g_page_size;
+	/* we add another page since we make resident a bit more datas */
+	SetHandleSize(krsrc, newSize + g_page_size);
+	if (GetHandleSize(krsrc) != (newSize + g_page_size)) {
+		dt_printf(dct, "Can't resize boostrap, err: %d\n",
+			MemError());
+		DisposeHandle(krsrc);
+		goto error;
+	}
+	HLock(krsrc);
+	
+	loc = *krsrc;
+	loc = (Ptr)PAGE_ALIGN(loc);
+	if (loc != *krsrc) {
+		dt_printf(dct, "Boostrap moved from 0x%lx to 0x%lx\n",
+			*krsrc, loc);
+		BlockMove(*krsrc, loc, origSize);
+	}
+	*outMapBegin = (UInt32*)(loc + extOrigSize);
+	*outTotalSize = newSize;
+	
+	err = GetMemFragment(loc, origSize, "\x09""bootstrap", kPrivateCFragCopy, &fragID, &fragEntry, errStr);
+	if (err != noErr) {
+		dt_printf(dct, "Boostrap preparation failed, err: %d (%#s)\n",
+			err, errStr);
+		DisposeHandle(krsrc);
+		goto error;
+	}
+	
+	return ((void **)fragEntry)[0];
+	
+error:
+	return NULL;
+}
+
+int
+check_kernel_format(int *out_flags, UInt8 **kern, UInt32 *kern_size,
+					UInt8 **out_rd, UInt32 *out_rds)
+{
+	Elf32_Ehdr* e;
+	struct external_filehdr* xc;
+	UInt32 orig_size;
+	UInt8* orig_kern;
+
+	orig_kern = *kern;
+	orig_size = *kern_size;
+	*out_rd = NULL;
+	*out_rds = 0;
+	
+	e = (Elf32_Ehdr *)orig_kern;
+	xc = (struct external_filehdr *)orig_kern;
+	
+	/* Check if it is an executable elf binary. */
+	if (e->e_ident[EI_MAG0] == ELFMAG0 && e->e_ident[EI_MAG1] == ELFMAG1 &&
+		  e->e_ident[EI_MAG2] == ELFMAG2 && e->e_ident[EI_MAG3] == ELFMAG3) {
+		dt_printf(dct, "ELF kernel\n");
+		*out_flags = KERNEL_ELF;
+		return noErr;
+	}
+	
+	/* Check if this is an xcoff */
+#define CHECK_MAGIC(xc,m) (get_16be(xc->f_magic) == (m))
+	if ((get_16be(xc->f_magic) == 0735) || (get_16be(xc->f_magic) == 0730)
+		|| (get_16be(xc->f_magic) == 0737)) {
+    	struct external_scnhdr *sp;
+	    struct external_scnhdr *isect, *rsect;
+	    int ns, oh, i;
+	    unsigned sa, len;
+	    void *dst;
+	    
+		dt_printf(dct, "XCOFF kernel (zImage)\n");
+		*out_flags = KERNEL_XCOFF | KERNEL_GZIPPED;
+	    ns = get_16be(xc->f_nscns);
+	    oh = get_16be(xc->f_opthdr);
+	    sp = (struct external_scnhdr *) (orig_kern + sizeof(struct external_filehdr) + oh);
+	    isect = rsect = NULL;
+	    for (i = 0; i < ns; ++i, ++sp) {
+			if (strcmp(sp->s_name, "image") == 0)
+			    isect = sp;
+			else if (strcmp(sp->s_name, "initrd") == 0)
+			    rsect = sp;
+	    }
+	    if (isect == NULL)
+			dt_printf(dct, "image section not found\n");
+		else {
+			*kern = orig_kern + get_32be(isect->s_scnptr);
+			*kern_size = get_32be(isect->s_size);
+			if (rsect != NULL) {
+				*out_rd = orig_kern + get_32be(rsect->s_scnptr);
+				*out_rds = get_32be(rsect->s_size);
+				dt_printf(dct, "ramdisk found, size: %dKb\n", *out_rds);
+			}
+			return noErr;
+		}
+	}
+	
+	/* This could be a gzipped file */
+    if (orig_kern[2] == DEFLATED && (orig_kern[3] & RESERVED) == 0) {
+		dt_printf(dct, "gzipped kernel\n");
+		*out_flags = KERNEL_ELF | KERNEL_GZIPPED;
+		return noErr;
+    }
+	
+	return -1;
+}
+

Added: trunk/miboot/src/nr_wrapper.c
===================================================================
--- trunk/miboot/src/nr_wrapper.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/nr_wrapper.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,694 @@
+#include "nr_wrapper.h"
+#include "debug_text.h"
+
+#include <CodeFragments.h>
+#include <MixedMode.h>
+
+enum {
+	kRegistryEntryIDInit,
+	kRegistryEntryIDCompare,
+	kRegistryEntryIDCopy,
+	kRegistryEntryIDDispose,
+	kRegistryCStrEntryCreate,
+	kRegistryEntryDelete,
+	kRegistryEntryCopy,
+	kRegistryEntryIterateCreate,
+	kRegistryEntryIterateDispose,
+	kRegistryEntryIterateSet,
+	kRegistryEntryIterate,
+	kRegistryEntrySearch,
+	kRegistryCStrEntryLookup,
+	kRegistryEntryToPathSize,
+	kRegistryCStrEntryToPath,
+	kRegistryCStrEntryToName,
+	kRegistryPropertyCreate,
+	kRegistryPropertyDelete,
+	kRegistryPropertyRename,
+	kRegistryPropertyIterateCreate,
+	kRegistryPropertyIterateDispose,
+	kRegistryPropertyIterate,
+	kRegistryPropertyGetSize,
+	kRegistryPropertyGet,
+	kRegistryPropertySet,
+	kRegistryEntryGetMod,
+	kRegistryEntrySetMod,
+	kRegistryPropertyGetMod,
+	kRegistryPropertySetMod,
+	kRegistryEntryMod,
+	kRegistryEntryPropertyMod,
+	
+	kRegistryCount
+};
+
+static UniversalProcPtr		__nr_symbols[kRegistryCount];
+static CFragConnectionID	__nr_connID;
+
+extern dt_context*	dct;
+
+
+OSStatus
+init_nr_wrappers()
+{
+	OSStatus				err;
+	Ptr						mainAddr;
+	Str255	 				errMessage;
+	CFragSymbolClass		symClass;
+	Ptr						symbol;
+	
+	err = GetSharedLibrary(	"\x0f""NameRegistryLib",
+							kPowerPCCFragArch,
+							kReferenceCFrag,
+							&__nr_connID,
+							&mainAddr,
+							errMessage);
+	if (err != noErr) {
+		dt_printf(dct, "GetSharedLibrary() failed <%#s>\n", errMessage);
+		return err;
+	}
+	
+#define LOOKUP_SYMBOL(id, name, procInfo)	\
+		err = FindSymbol(__nr_connID, name, &symbol,&symClass);	\
+		if (err == noErr)	{\
+			__nr_symbols[id] = NewRoutineDescriptorTrap(	\
+				(ProcPtr)symbol, procInfo, kPowerPCISA);	\
+		} else {\
+			__nr_symbols[id] = NULL; \
+		}
+			
+	LOOKUP_SYMBOL(kRegistryEntryIDInit,
+		"\x13""RegistryEntryIDInit",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryIDCompare,
+		"\x16""RegistryEntryIDCompare",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryIDCopy,
+		"\x13""RegistryEntryIDCopy",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryIDDispose,
+		"\x16""RegistryEntryIDDispose",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryCStrEntryCreate,
+		"\x17""RegistryCStrEntryCreate",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegCStrPathName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryDelete,
+		"\x13""RegistryEntryDelete",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryCopy,
+		"\x11""RegistryEntryCopy",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryIterateCreate,
+		"\x1a""RegistryEntryIterateCreate",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryIter *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryIterateDispose,
+		"\x1b""RegistryEntryIterateDispose",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryIter *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryIterateSet,
+		"\x17""RegistryEntryIterateSet",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryIter *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryIterate,
+		"\x14""RegistryEntryIterate",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryIter *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryIterationOp)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntrySearch,
+		"\x13""RegistryEntrySearch",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryIter *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryIterationOp)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *)))
+		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(void *)))
+		 | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(RegPropertyValueSize)))
+	)
+	LOOKUP_SYMBOL(kRegistryCStrEntryLookup,
+		"\x17""RegistryCStrEntryLookup",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegCStrPathName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegEntryID *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryToPathSize,
+		"\x17""RegistryEntryToPathSize",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPathNameSize *)))
+	)
+	LOOKUP_SYMBOL(kRegistryCStrEntryToPath,
+		"\x17""RegistryCStrEntryToPath",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegCStrPathName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegPathNameSize)))
+	)
+	LOOKUP_SYMBOL(kRegistryCStrEntryToName,
+		"\x17""RegistryCStrEntryToName",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegCStrEntryName *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyCreate,
+		"\x16""RegistryPropertyCreate",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(RegPropertyValueSize)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyDelete,
+		"\x16""RegistryPropertyDelete",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyRename,
+		"\x16""RegistryPropertyRename",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegPropertyName *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyIterateCreate,
+		"\x1d""RegistryPropertyIterateCreate",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyIter *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyIterateDispose,
+		"\x1e""RegistryPropertyIterateDispose",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegPropertyIter *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyIterate,
+		"\x17""RegistryPropertyIterate",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegPropertyIter *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyGetSize,
+		"\x17""RegistryPropertyGetSize",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegPropertyValueSize *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyGet,
+		"\x13""RegistryPropertyGet",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(RegPropertyValueSize *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertySet,
+		"\x13""RegistryPropertySet",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(RegPropertyValueSize)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryGetMod,
+		"\x13""RegistryEntryGetMod",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryModifiers *)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntrySetMod,
+		"\x13""RegistryEntrySetMod",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryModifiers)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertyGetMod,
+		"\x16""RegistryPropertyGetMod",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegPropertyModifiers *)))
+	)
+	LOOKUP_SYMBOL(kRegistryPropertySetMod,
+		"\x16""RegistryPropertySetMod",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegPropertyName *)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegPropertyModifiers)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryMod,
+		"\x10""RegistryEntryMod",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryIter *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryIterationOp)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *)))
+		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(RegEntryModifiers)))
+	)
+	LOOKUP_SYMBOL(kRegistryEntryPropertyMod,
+		"\x18""RegistryEntryPropertyMod",
+		kCStackBased
+		 | RESULT_SIZE(SIZE_CODE(sizeof(OSStatus)))
+		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(RegEntryIter *)))
+		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(RegEntryIterationOp)))
+		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(RegEntryID *)))
+		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *)))
+		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(RegEntryModifiers)))
+	)
+	
+	return noErr;
+}
+
+OSStatus
+dispose_nr_wrappers(void)
+{
+	int i;
+	
+	for(i=0; i<kRegistryCount; i++) {
+		if (__nr_symbols[i]) {
+			DisposeRoutineDescriptorTrap(__nr_symbols[i]);
+			__nr_symbols[i] = NULL;
+		}
+	}
+	CloseConnection(&__nr_connID);
+}
+
+
+OSStatus
+RegistryEntryIDInit				(RegEntryID *			id)
+{
+	if (__nr_symbols[kRegistryEntryIDInit] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryID *))(__nr_symbols[kRegistryEntryIDInit]))(id);
+}
+
+Boolean
+RegistryEntryIDCompare			(const RegEntryID *		id1,
+								 const RegEntryID *		id2)
+{
+	if (__nr_symbols[kRegistryEntryIDCompare] == NULL)
+		return false;
+	return ((OSStatus (*)(const RegEntryID *, const RegEntryID *))
+		(__nr_symbols[kRegistryEntryIDCompare]))(id1, id2);
+}
+
+OSStatus
+RegistryEntryIDCopy				(const RegEntryID *		src,
+								 RegEntryID *			dst)
+{
+	if (__nr_symbols[kRegistryEntryIDCopy] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID *,RegEntryID *))
+		(__nr_symbols[kRegistryEntryIDCopy]))(src,dst);
+}
+
+OSStatus
+RegistryEntryIDDispose			(RegEntryID *			id)
+{
+	if (__nr_symbols[kRegistryEntryIDDispose] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryID *))(__nr_symbols[kRegistryEntryIDDispose]))(id);
+}
+
+OSStatus
+RegistryCStrEntryCreate			(const RegEntryID *		parentEntry,
+								 const RegCStrPathName * name,
+								 RegEntryID *			newEntry)
+{
+	if (__nr_symbols[kRegistryCStrEntryCreate] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID *,const RegCStrPathName *,RegEntryID *))
+		(__nr_symbols[kRegistryCStrEntryCreate]))(parentEntry,name,newEntry);
+}								 
+
+OSStatus
+RegistryEntryDelete				(const RegEntryID *		id)
+{
+	if (__nr_symbols[kRegistryEntryDelete] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID *))(__nr_symbols[kRegistryEntryDelete]))(id);
+}
+
+OSStatus
+RegistryEntryCopy				(RegEntryID *			parentEntryID,
+								 RegEntryID *			sourceDevice,
+								 RegEntryID *			destDevice)
+{
+	if (__nr_symbols[kRegistryEntryCopy] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryID *,RegEntryID *,RegEntryID *))
+		(__nr_symbols[kRegistryEntryCopy]))(parentEntryID,sourceDevice,destDevice);
+}
+
+OSStatus
+RegistryEntryIterateCreate		(RegEntryIter *			cookie)
+{
+	if (__nr_symbols[kRegistryEntryIterateCreate] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryIter *))(__nr_symbols[kRegistryEntryIterateCreate]))(cookie);
+}
+
+OSStatus
+RegistryEntryIterateDispose		(RegEntryIter *			cookie)
+{
+	if (__nr_symbols[kRegistryEntryIterateDispose] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryIter *))(__nr_symbols[kRegistryEntryIterateDispose]))(cookie);
+}
+
+OSStatus
+RegistryEntryIterateSet			(RegEntryIter *			cookie,
+								 const RegEntryID *		startEntryID)
+{
+	if (__nr_symbols[kRegistryEntryIterateSet] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryIter*,const RegEntryID*))
+		(__nr_symbols[kRegistryEntryIterateSet]))
+		(cookie, startEntryID);
+}
+
+OSStatus
+RegistryEntryIterate			(RegEntryIter *			cookie,
+								 RegEntryIterationOp 	relationship,
+								 RegEntryID *			foundEntry,
+								 Boolean *				done)
+{
+	if (__nr_symbols[kRegistryEntryIterate] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryIter*,RegEntryIterationOp,RegEntryID*,Boolean*))
+		(__nr_symbols[kRegistryEntryIterate]))
+		(cookie, relationship, foundEntry, done);
+}
+
+OSStatus
+RegistryEntrySearch				(RegEntryIter *			cookie,
+								 RegEntryIterationOp 	relationship,
+								 RegEntryID *			foundEntry,
+								 Boolean *				done,
+								 const RegPropertyName * propertyName,
+								 const void *			propertyValue,
+								 RegPropertyValueSize 	propertySize)
+{
+	if (__nr_symbols[kRegistryEntrySearch] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryIter*,RegEntryIterationOp,RegEntryID*,Boolean*,
+		const RegPropertyName*,const void*,RegPropertyValueSize))
+		(__nr_symbols[kRegistryEntrySearch]))
+		(cookie,relationship,foundEntry,done,propertyName,propertyValue,propertySize);
+}
+
+OSStatus
+RegistryCStrEntryLookup			(const RegEntryID *		searchPointID,
+								 const RegCStrPathName * pathName,
+								 RegEntryID *			foundEntry)
+{
+	if (__nr_symbols[kRegistryCStrEntryLookup] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegCStrPathName*,RegEntryID*))
+		(__nr_symbols[kRegistryCStrEntryLookup]))
+		(searchPointID,pathName,foundEntry);
+}
+
+OSStatus
+RegistryEntryToPathSize			(const RegEntryID *		entryID,
+								 RegPathNameSize *		pathSize)
+{
+	if (__nr_symbols[kRegistryEntryToPathSize] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,RegPathNameSize*))
+		(__nr_symbols[kRegistryEntryToPathSize]))
+		(entryID,pathSize);
+}
+
+OSStatus
+RegistryCStrEntryToPath			(const RegEntryID *		entryID,
+								 RegCStrPathName *		pathName,
+								 RegPathNameSize 		pathSize)
+{
+	if (__nr_symbols[kRegistryCStrEntryToPath] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,RegCStrPathName*,RegPathNameSize))
+		(__nr_symbols[kRegistryCStrEntryToPath]))
+		(entryID,pathName,pathSize);
+}
+
+OSStatus
+RegistryCStrEntryToName			(const RegEntryID *		entryID,
+								 RegEntryID *			parentEntry,
+								 RegCStrEntryName *		nameComponent,
+								 Boolean *				done)
+{
+	if (__nr_symbols[kRegistryCStrEntryToName] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,RegEntryID*,RegCStrEntryName*,Boolean*))
+		(__nr_symbols[kRegistryCStrEntryToName]))
+		(entryID,parentEntry,nameComponent,done);
+}
+
+OSStatus
+RegistryPropertyCreate			(const RegEntryID *		entryID,
+								 const RegPropertyName * propertyName,
+								 const void *			propertyValue,
+								 RegPropertyValueSize 	propertySize)
+{
+	if (__nr_symbols[kRegistryPropertyCreate] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*,const void*,
+		RegPropertyValueSize))
+		(__nr_symbols[kRegistryPropertyCreate]))
+		(entryID,propertyName,propertyValue,propertySize);
+}
+
+OSStatus
+RegistryPropertyDelete			(const RegEntryID *		entryID,
+								 const RegPropertyName * propertyName)
+{
+	if (__nr_symbols[kRegistryPropertyDelete] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*))
+		(__nr_symbols[kRegistryPropertyDelete]))
+		(entryID,propertyName);
+}
+
+OSStatus
+RegistryPropertyRename			(const RegEntryID *		entry,
+								 const RegPropertyName * oldName,
+								 const RegPropertyName * newName)
+{
+	if (__nr_symbols[kRegistryPropertyRename] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*,const RegPropertyName*))
+		(__nr_symbols[kRegistryPropertyRename]))
+		(entry,oldName,newName);
+}
+
+OSStatus
+RegistryPropertyIterateCreate	(const RegEntryID *		entry,
+								 RegPropertyIter *		cookie)
+{
+	if (__nr_symbols[kRegistryPropertyIterateCreate] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,RegPropertyIter*))
+		(__nr_symbols[kRegistryPropertyIterateCreate]))
+		(entry,cookie);
+}
+								 
+OSStatus
+RegistryPropertyIterateDispose	(RegPropertyIter *		cookie)
+{
+	if (__nr_symbols[kRegistryPropertyIterateDispose] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegPropertyIter*))
+		(__nr_symbols[kRegistryPropertyIterateDispose]))
+		(cookie);
+}
+
+OSStatus
+RegistryPropertyIterate			(RegPropertyIter *		cookie,
+								 RegPropertyName *		foundProperty,
+								 Boolean *				done)
+{
+	if (__nr_symbols[kRegistryPropertyIterate] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegPropertyIter*,RegPropertyName*,Boolean*))
+		(__nr_symbols[kRegistryPropertyIterate]))
+		(cookie,foundProperty,done);
+}
+
+OSStatus
+RegistryPropertyGetSize			(const RegEntryID *		entryID,
+								 const RegPropertyName * propertyName,
+								 RegPropertyValueSize *	propertySize)
+{
+	if (__nr_symbols[kRegistryPropertyGetSize] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*,RegPropertyValueSize*))
+		(__nr_symbols[kRegistryPropertyGetSize]))
+		(entryID,propertyName,propertySize);
+}
+
+OSStatus
+RegistryPropertyGet				(const RegEntryID *		entryID,
+								 const RegPropertyName * propertyName,
+								 void *					propertyValue,
+								 RegPropertyValueSize *	propertySize)
+{
+	if (__nr_symbols[kRegistryPropertyGet] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*,void*,RegPropertyValueSize*))
+		(__nr_symbols[kRegistryPropertyGet]))
+		(entryID,propertyName,propertyValue,propertySize);
+}
+
+OSStatus
+RegistryPropertySet				(const RegEntryID *		entryID,
+								 const RegPropertyName * propertyName,
+								 const void *			propertyValue,
+								 RegPropertyValueSize 	propertySize)
+{
+	if (__nr_symbols[kRegistryPropertySet] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*,const void*,RegPropertyValueSize))
+		(__nr_symbols[kRegistryPropertySet]))
+		(entryID,propertyName,propertyValue,propertySize);
+}
+
+OSStatus
+RegistryEntryGetMod				(const RegEntryID *		entry,
+								 RegEntryModifiers *	modifiers)
+{
+	if (__nr_symbols[kRegistryEntryGetMod] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,RegEntryModifiers *))
+		(__nr_symbols[kRegistryEntryGetMod]))
+		(entry,modifiers);
+}
+
+OSStatus
+RegistryEntrySetMod				(const RegEntryID *		entry,
+								 RegEntryModifiers 		modifiers)
+{
+	if (__nr_symbols[kRegistryEntrySetMod] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,RegEntryModifiers))
+		(__nr_symbols[kRegistryEntrySetMod]))
+		(entry,modifiers);
+}								 
+
+OSStatus
+RegistryPropertyGetMod			(const RegEntryID *		entry,
+								 const RegPropertyName * name,
+								 RegPropertyModifiers *	modifiers)
+{
+	if (__nr_symbols[kRegistryPropertyGetMod] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*,RegPropertyModifiers*))
+		(__nr_symbols[kRegistryPropertyGetMod]))
+		(entry,name,modifiers);
+}								 
+
+OSStatus
+RegistryPropertySetMod			(const RegEntryID *		entry,
+								 const RegPropertyName * name,
+								 RegPropertyModifiers 	modifiers)
+{
+	if (__nr_symbols[kRegistryPropertySetMod] == NULL)
+		return -1;
+	return ((OSStatus (*)(const RegEntryID*,const RegPropertyName*,RegPropertyModifiers))
+		(__nr_symbols[kRegistryPropertySetMod]))
+		(entry,name,modifiers);
+}								 
+
+
+OSStatus
+RegistryEntryMod				(RegEntryIter *			cookie,
+								 RegEntryIterationOp 	relationship,
+								 RegEntryID *			foundEntry,
+								 Boolean *				done,
+								 RegEntryModifiers 		matchingModifiers)
+{
+	if (__nr_symbols[kRegistryEntryMod] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryIter*,RegEntryIterationOp,RegEntryID*,
+		Boolean*,RegEntryModifiers))
+		(__nr_symbols[kRegistryEntryMod]))
+		(cookie, relationship, foundEntry, done, matchingModifiers);
+}
+
+OSStatus
+RegistryEntryPropertyMod		(RegEntryIter *			cookie,
+								 RegEntryIterationOp 	relationship,
+								 RegEntryID *			foundEntry,
+								 Boolean *				done,
+								 RegPropertyModifiers 	matchingModifiers)
+{
+	if (__nr_symbols[kRegistryEntryPropertyMod] == NULL)
+		return -1;
+	return ((OSStatus (*)(RegEntryIter*,RegEntryIterationOp,RegEntryID*,
+		Boolean*,RegEntryModifiers))
+		(__nr_symbols[kRegistryEntryPropertyMod]))
+		(cookie, relationship, foundEntry, done, matchingModifiers);
+}
+								 
+

Added: trunk/miboot/src/nr_wrapper.h
===================================================================
--- trunk/miboot/src/nr_wrapper.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/nr_wrapper.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,9 @@
+#ifndef __NR_WRAPPER_H__
+#define __NR_WRAPPER_H__
+
+#include <NameRegistry.h>
+
+extern OSStatus	init_nr_wrappers(void);
+extern OSStatus	dispose_nr_wrappers(void);
+
+#endif

Added: trunk/miboot/src/pre_strap_ppc.c
===================================================================
--- trunk/miboot/src/pre_strap_ppc.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/pre_strap_ppc.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,703 @@
+/* This code fragments provides the low-level 68k boot code
+   with some PPC functions (necessary for using the name
+   registry API for example).
+ */
+ 
+#include <PCI.h>
+#include <Errors.h>
+#include <MixedMode.h>
+#include <CodeFragments.h>
+#include <Gestalt.h>
+#include <NameRegistry.h>
+
+#include "bootx.h"
+#include "LowLevelBoot.h"
+#include "debug_text.h"
+
+#define DEBUG	0
+
+#ifndef BROKEN_THIRD_PARTY_CARDS
+#define BROKEN_THIRD_PARTY_CARDS	1
+#endif
+
+#define MAX_STRING_PROP_SIZE	256
+#define MAX_ASSIGNED_ADDRESSES	8
+
+#define	kPCIConfigCommandAddress		0x04		/* PCI "Command" config register address	*/
+#define		cwCommandEnableMemorySpace	0x0002		/*   enable memory space bit */
+#define		cwCommandEnableIOSpace		0x0001		/*   enable i/o space bit */
+
+/* Exported */
+extern pascal void* start(void);
+extern pascal void ShutDownDevices(dt_context *in_dct, boot_infos_t* bi);
+UInt32 __procinfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(void*)));
+
+typedef void (*iterate_device_proc)(RegEntryIDPtr entryID);
+
+static OSErr	iterate_devices(iterate_device_proc	proc);
+static SInt32	read_pci_config_reg(RegEntryIDPtr entryID, int reg);
+static UInt32	get_assigned_addresses(RegEntryIDPtr entryID, PCIAssignedAddress* outAddresses);
+static void		get_string_property(RegEntryIDPtr entryID, char* prop_name, char *out_string);
+static UInt32	get_io_addresses(RegEntryIDPtr entryID, UInt32 *out_addresses);
+static Boolean	check_vendor_device_id(RegEntryIDPtr entryID, UInt16 vendorID, UInt16 deviceID);
+static OSStatus	get_one_property(	RegEntryIDPtr			regEntryIDPtr,
+									RegPropertyNamePtr		regPropertyName,
+									RegPropertyValue		*regPropertyValuePtr,
+									RegPropertyValueSize	*regPropertyValueSizePtr);
+
+static void		reset_apple_SCSI_UW_board(RegEntryIDPtr entryID);
+static void		reset_apple_DBDMA_channels(RegEntryIDPtr entryID);
+static void		reset_apple_USB(RegEntryIDPtr entryID);
+static void		reset_ATI_mach64_master(RegEntryIDPtr entryID);
+static void		remap_PDM_video(void);
+
+static dt_context *dct;
+
+UInt32 strlen(char * s) {
+	const char *sc;
+	for (sc = s; *sc != '\0'; ++sc) ;
+	return sc - s;
+}
+void memset(void *p, int c, UInt32 s) {
+	while(s--)
+		((char *)p)[s] = (char)c;
+}
+void memcpy(void* d, void* s, UInt32 z) {
+	BlockMove(s,d,z); /* BlockMoveData ? */
+}
+void memmove(void* d, void* s, UInt32 z) {
+	BlockMove(s,d,z); /* BlockMoveData ? */
+}
+int strcmp(const char * cs,const char * ct) {
+	char __res;
+	while (1) {
+		if ((__res = *cs - *ct++) != 0 || !*cs++)
+			break;
+	}
+	return __res;
+}
+char * strcat(char * dest, const char * src) {
+	char *tmp = dest;
+	while (*dest) dest++;
+	while ((*dest++ = *src++) != '\0') ;
+	return tmp;
+}
+int strncmp(const char * cs,const char * ct,UInt32 count)
+{
+	char __res = 0;
+	while (count) {
+		if ((__res = *cs - *ct++) != 0 || !*cs++)
+			break;
+		count--;
+	}
+	return __res;
+}
+
+RoutineDescriptor	g_desc = BUILD_ROUTINE_DESCRIPTOR(uppLowLevelBootPPCProcInfo, ShutDownDevices);
+
+pascal void*
+start(void)
+{
+//	return (void *)NewRoutineDescriptor((ProcPtr)ShutDownDevices, uppLowLevelBootPPCProcInfo, kPowerPCISA);
+	return &g_desc;
+}
+
+pascal void
+ShutDownDevices(dt_context *in_dct, boot_infos_t* bi)
+{
+	dct = in_dct;
+	
+	dt_printf(dct, "Shutting down devices...\n");
+	
+	/* NuBus: Change address of PDM framebuffer */
+	if ((long)RegistryEntryIDInit == kUnresolvedCFragSymbolAddress) {
+		dt_printf(dct, "No name registry !\n");
+		if (bi->architecture & BOOT_ARCH_NUBUS_PDM) {
+			/* This should definitely be smarter !!! */
+			if ((UInt32)bi->dispDeviceBase <= 0x100000) {
+				int i;
+				remap_PDM_video();
+				bi->logicalDisplayBase = (UInt8*)0x100000;
+				bi->dispDeviceBase = (UInt8*)0x100000;
+				for(i=0; i<bi->physMemoryMapSize; i++) {
+					if ((bi->physMemoryMap[i].physAddr <= (UInt32)bi->dispDeviceBase) &&
+						((bi->physMemoryMap[i].physAddr + bi->physMemoryMap[i].size)
+							> (UInt32)bi->dispDeviceBase)) {
+						int count = bi->physMemoryMapSize;
+						int size = bi->physMemoryMap[i].size;
+						memmove(&bi->physMemoryMap[i+1], &bi->physMemoryMap[i],
+							sizeof(boot_info_map_entry_t) * (count-i-1));
+						bi->physMemoryMap[i].size = (UInt32)bi->dispDeviceBase - bi->physMemoryMap[i].physAddr;
+						bi->physMemoryMap[i+1].physAddr = (UInt32)bi->dispDeviceBase + 0x100000;
+						bi->physMemoryMap[i+1].size = (size + bi->physMemoryMap[i].physAddr - bi->physMemoryMap[i+1].physAddr);
+						break;
+					}
+				}		
+			}
+		}
+	} else {
+		/* PCI: Disable DMA on known devices */
+		iterate_devices(reset_apple_SCSI_UW_board);
+		iterate_devices(reset_apple_DBDMA_channels);
+		iterate_devices(reset_apple_USB);
+		iterate_devices(reset_ATI_mach64_master);
+	}
+}
+
+#if defined(__GNUC__)
+
+static inline void
+__eieio()
+{
+	__asm__ __volatile__ (
+		"eieio"
+	:
+	:
+	:	"memory"
+	);
+}
+
+static inline unsigned int
+__lwbrx(unsigned int *base, unsigned int index)
+{
+	unsigned int value;
+	__asm__ __volatile__ (
+		"lwbrx %0, %1, %2"
+	:	"=r" (value)
+	:	"b" (base), "r" (index)
+	);
+	return value;
+}
+
+static inline void
+__stwbrx(unsigned int value, unsigned int *base, unsigned int index)
+{
+	__asm__ __volatile__ (
+		"stwbrx %0, %1, %2"
+	:
+	:	"r" (value), "b" (base), "r" (index)
+	:	"memory"
+	);
+}
+
+#endif
+
+#if BROKEN_THIRD_PARTY_CARDS
+
+#if defined(__GNUC__)
+static inline void
+fixed_eieio(void) {
+	__asm__ __volatile__ (
+		"li %r0,0\n\t"
+		"cmpwi %r0,0\n\t"
+		"bne+ 0f\n\t"
+		"eieio\n"
+		"0:"
+	);
+}
+#else
+inline asm fixed_eieio(void) {
+	li r0,0;
+	cmpwi r0,0;
+	bne+ toto;
+	eieio;
+	toto:;
+}
+#endif
+
+#else /* BROKEN_THIRD_PARTY_CARDS */
+
+#define fixed_eieio()	__eieio()
+
+#endif /* BROKEN_THIRD_PARTY_CARDS */
+
+static void
+remap_PDM_video(void)
+{
+	unsigned char savevalue[35];
+	int i;
+	
+	*((volatile unsigned char *)0x50F40008) = 0;	/* reset bit counter */
+	fixed_eieio();
+	for (i=0; i<35; i++) {
+		savevalue[i] = *((volatile unsigned char *)0x50F40000);
+		fixed_eieio();
+	}
+
+	savevalue[33] = 0;	/* change Video Base to 1Mb */
+
+	*((volatile unsigned char *)0x50F40008) = 0;	/* reset bit counter again */
+	fixed_eieio();
+	for (i=0; i<35; i++) {
+		*((volatile unsigned char *)0x50F40000) = savevalue[i];
+		fixed_eieio();
+	}
+}
+
+static void
+get_string_property(RegEntryIDPtr entryID, char* prop_name, char *out_string)
+{
+	OSErr					err;
+	RegPropertyValueSize	size;
+		
+	size = MAX_STRING_PROP_SIZE-1;
+	
+	err = RegistryPropertyGet(entryID, prop_name, out_string, &size);
+	if (err == noErr)
+		out_string[size] = 0;
+	else
+		out_string[0] = 0;
+
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This is a generic function that retrieves a property from the Name Registry,
+ * allocating memory for it in the system pool. It looks in the Name Registry entry
+ * for this driver -- the DriverInitializeCmd passed this as one of its parameters.
+ * This sample is specific to device drivers: it allocates the property in the resident
+ * memory pool.
+ */
+OSStatus
+get_one_property(
+		RegEntryIDPtr			regEntryIDPtr,			/* Driver's Name Registery ID	*/
+		RegPropertyNamePtr		regPropertyName,
+		RegPropertyValue		*regPropertyValuePtr,
+		RegPropertyValueSize	*regPropertyValueSizePtr
+	)
+{
+		OSStatus				status;
+
+		/*
+		 * In addition to getting the size of a property, this function will fail if
+		 * the property is not present in the registry. We NULL the result before
+		 * starting so we can dispose of the property even if this function failed.
+		 */
+		status = RegistryPropertyGetSize(
+					regEntryIDPtr,
+					regPropertyName,
+					regPropertyValueSizePtr
+				);
+		if (status == noErr) {
+			status = RegistryPropertyGet(
+						regEntryIDPtr,
+						regPropertyName,
+						regPropertyValuePtr,
+						regPropertyValueSizePtr
+					);
+			if (status != noErr)
+				dt_printf(dct, "RegistryPropertyGet failed (err:%d)\n", status);
+		}
+		return (status);
+}
+
+static PCIAssignedAddress	g_assigned_addresses[8];
+static LogicalAddress		g_logical_addresses[8];
+
+static UInt32
+count_assigned_addresses(RegEntryIDPtr entryID)
+{
+	OSErr					err;
+	RegPropertyValueSize	size;
+
+	size = MAX_ASSIGNED_ADDRESSES * sizeof(PCIAssignedAddress);
+
+	err = RegistryPropertyGet(entryID, kPCIAssignedAddressProperty, g_assigned_addresses, &size);
+	if (err == noErr)
+		return size/sizeof(PCIAssignedAddress);
+	else
+		return 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * GetDeviceLogicalAddress
+ *
+ * Retrieve the assigned-address property from the Name Registry and search it for
+ * the specified addressSpaceSelector. This function uses the device base register
+ * only: it ignores the I/O vs. Memory space selector. It will need modification if
+ * the hardware supports 64-bit addressing or needs to understand address spaces.
+ */
+OSStatus
+get_logical_address(
+		RegEntryIDPtr			regEntryIDPtr,			/* Driver's Name Registery ID	*/
+		PCIRegisterNumber		deviceRegister,			/* Register in address property	*/
+		LogicalAddress			*deviceLogicalAddress,	/* Gets the logical address		*/
+		ByteCount				*deviceAreaLength		/* Gets the area size			*/
+	)
+{
+		OSStatus				status;
+		UInt32					i;						/* Vector index					*/
+		UInt32					nAddresses;				/* Number of vector elements	*/
+		RegPropertyValueSize	assignedAddressSize;
+		RegPropertyValueSize	logicalAddressSize;
+		PCIAssignedAddressPtr	pciAssignedAddressPtr;	/* Assigned Address element ptr	*/
+		StringPtr				failureMsg;
+		
+		failureMsg				= NULL;
+		
+		if (deviceLogicalAddress == NULL)
+			status = paramErr;
+		else {
+			/*
+			 * Fetch the assigned address and AAPL,address properties. Allocate memory
+			 * for each.
+			 */
+			status = get_one_property(
+						regEntryIDPtr,
+						kPCIAssignedAddressProperty,
+						(RegPropertyValue*)g_assigned_addresses,
+						&assignedAddressSize);
+			if (status != noErr)
+				dt_printf(dct, "No assigned-addresses property (err: %d)\n", status);
+		}
+		if (status == noErr) {
+#define kAAPLDeviceLogicalAddress	"AAPL,address"
+			status = get_one_property(
+						regEntryIDPtr,
+						kAAPLDeviceLogicalAddress,
+						(RegPropertyValue*)g_logical_addresses,
+						&logicalAddressSize
+					);
+			if (status != noErr)
+				dt_printf(dct, "No AAPL,address property (err: %d)\n", status);
+		}
+		if (status == noErr) {
+			status					= paramErr;
+			nAddresses				= assignedAddressSize / sizeof (PCIAssignedAddress);
+			pciAssignedAddressPtr	= (PCIAssignedAddressPtr) g_assigned_addresses;
+			
+			for (i = 0; i < nAddresses; i++, pciAssignedAddressPtr++) {
+				if (GetPCIRegisterNumber(pciAssignedAddressPtr) == deviceRegister) {
+					if (pciAssignedAddressPtr->size.hi != 0			/* 64-bit area?		*/
+					 || pciAssignedAddressPtr->size.lo == 0)
+					 {												/* Zero length		*/
+						/*
+						 * Open Firmware was unable to assign a valid address to this
+						 * memory area. We must return an error to prevent the driver
+						 * from starting up. Is there a better error status?
+						 */
+						status = paramErr;
+					}
+					else if (i >= (logicalAddressSize / sizeof (LogicalAddress))) {
+						/*
+						 * The logical address vector is too small -- this is a bug.
+						 */
+						status = paramErr;
+					}
+					else {
+						status = noErr;
+						*deviceLogicalAddress = g_logical_addresses[i];
+						if (deviceAreaLength)
+							*deviceAreaLength = pciAssignedAddressPtr->size.lo;
+					}
+					break; /* Exit loop when we find the desired register */
+				}
+			}
+			if (status != noErr)
+				dt_printf(dct, "No valid address space (err: %d)\n", status);
+		}
+
+		return (status);
+}
+
+static Boolean
+check_vendor_device_id(RegEntryIDPtr entryID, UInt16 vendorID, UInt16 deviceID)
+{
+	UInt32		pSize;
+	OSStatus	err;
+	UInt16		prop;
+	
+	pSize = 2;
+	err = RegistryPropertyGet(entryID, "vendor-id", &prop, &pSize);
+	if ((err != noErr)||(pSize != 2))
+		return false;
+	if (prop != vendorID)
+		return false;
+
+	pSize = 2;
+	err = RegistryPropertyGet(entryID, "device-id", &prop, &pSize);
+	if ((err != noErr)||(pSize != 2))
+		return false;
+	return (prop == deviceID);
+}
+
+static SInt32
+read_pci_config_reg(RegEntryIDPtr entryID, int reg)
+{
+	OSStatus	status;
+	UInt16		value;
+	
+	status = ExpMgrConfigReadWord(entryID, (LogicalAddress)reg, &value);
+	if (status != noErr)
+		return -1;
+	return value;
+}
+
+void
+reset_apple_DBDMA_channels(RegEntryIDPtr entryID)
+{
+	char				prop[MAX_STRING_PROP_SIZE];
+	UInt32				addrs_count;
+	UInt32				*io_base;
+	
+	get_string_property(entryID, "device_type", prop);
+	if (strcmp(prop, "dbdma") && strcmp(prop, "mac-io"))
+		return;
+		
+#if DEBUG
+	dt_printf(dct, "dbdma: ");
+#endif
+
+	addrs_count = count_assigned_addresses(entryID);
+	if (addrs_count < 1) {
+		dt_printf(dct, "dbdma: no addresses !\n");
+		return;
+	}
+
+	if (get_logical_address(entryID, 16, (LogicalAddress *)&io_base, NULL) != noErr) {
+		dt_printf(dct, "dbdma: can't get addresses !\n");
+		return;
+	}
+	
+	if (io_base) {
+		int i;
+		io_base += 0x2000;	/* base of DBDMA channels */
+#if DEBUG
+		dt_printf(dct, "dbdma: io_base = 0x%x\n", io_base);
+#endif		
+		for (i=0;i<16;i++) {
+			*(io_base) = 0x000000FCUL;
+			__eieio();
+			while((*(io_base+1)) & 0x00800000UL)
+				__eieio();
+		}
+	}
+#if DEBUG
+	else
+		dt_printf(dct, "dbdma: no io_base !\n");
+#endif		
+}
+
+void
+reset_apple_SCSI_UW_board(RegEntryIDPtr entryID)
+{
+	char				prop[MAX_STRING_PROP_SIZE];
+	Boolean				found = false;
+	Boolean				use_io = false;
+	char*				io_base;
+	SInt32				cmd;
+	UInt32				addrs_count;
+	
+	get_string_property(entryID, "name", prop);
+	found = (strcmp(prop, "Apple53C875Card") == 0);
+	if (!found)
+		found = check_vendor_device_id(entryID, 0x1000, 0xf);
+	if (!found) {
+		return;
+	}
+#if DEBUG
+	dt_printf(dct, "symbios: ");
+#endif	
+	
+	cmd = read_pci_config_reg(entryID, kPCIConfigCommandAddress);
+	use_io = (cmd > 0) && (cmd & cwCommandEnableIOSpace);
+#if DEBUG
+	dt_printf(dct, "%s", use_io ? "(io) " : "(mem) ");
+#endif
+	
+	addrs_count = count_assigned_addresses(entryID);
+	if (addrs_count < 2) {
+		dt_printf(dct, "symbios: not enough addresses !\n");
+		return;
+	}
+		
+	if (use_io) {
+		if (get_logical_address(entryID, 16, (LogicalAddress *)&io_base, NULL) != noErr) {
+			dt_printf(dct, "symbios: can't get addresses !\n");
+			return;
+		}
+		if (!io_base) {
+#if DEBUG
+			dt_printf(dct, "symbios: no io range ->mem");
+#endif			
+			use_io = false;
+		}
+	}
+	if (!use_io)
+		if (get_logical_address(entryID, 20, (LogicalAddress *)&io_base, NULL) != noErr) {
+			dt_printf(dct, "symbios: can't get addresses !\n");
+			return;
+		}
+	if (!io_base) {
+		dt_printf(dct, "symbios: no io base !");
+		return;
+	}
+
+#if DEBUG
+	dt_printf(dct, "symbios: base = 0x%x\n", io_base);
+#endif
+	
+	*(io_base + 0x14) = 0x40;
+	__eieio();
+}
+
+
+void
+reset_apple_USB(RegEntryIDPtr entryID)
+{
+	char				prop[MAX_STRING_PROP_SIZE];
+	UInt32				addrs_count;
+	UInt32				*io_base;
+	
+	get_string_property(entryID, "name", prop);
+	if (strcmp(prop, "usb"))
+		return;
+	get_string_property(entryID, "device_type", prop);
+	if (strcmp(prop, "usb"))
+		return;
+		
+#if DEBUG
+	dt_printf(dct, "usb: ");
+#endif
+
+	addrs_count = count_assigned_addresses(entryID);
+	if (addrs_count < 1) {
+		dt_printf(dct, "usb: not enough addresses !\n");
+		return;
+	}
+
+	if (get_logical_address(entryID, 16, (LogicalAddress *)&io_base, NULL) != noErr) {
+		dt_printf(dct, "usb:can't get addresses !\n");
+		return;
+	}
+	if (!io_base) {
+		dt_printf(dct, "usb: no io base !");
+		return;
+	}
+	
+#if DEBUG
+	dt_printf(dct, "usb: base = 0x%x\n", io_base);
+#endif	
+	*(io_base + 0x02) = 0x01000000UL;
+	__eieio();
+}
+
+#define ATI_BUS_MSTR_RESET		0x00000002
+#define ATI_BUS_FLUSH_BUF		0x00000004
+#define ATI_BUS_CNTL			0x00a0
+#define ATI_GUI_ENGINE_ENABLE	0x0100
+#define ATI_GEN_TEST_CNTL		0x00d0
+#define ATI_BUS_HOST_ERR_ACK	0x00800000
+#define ATI_BUS_FIFO_ERR_ACK	0x00200000
+
+static inline void ati_regw(unsigned long base_addr, volatile unsigned long regindex, unsigned long regdata)
+{
+  	__stwbrx(regdata, (void *)base_addr, (int)regindex);
+	__eieio();
+}
+
+static inline unsigned long ati_regr(unsigned long base_addr, volatile unsigned long regindex)
+{
+	unsigned long val;
+  	
+  	val = __lwbrx((void *)base_addr, regindex);
+	__eieio();
+
+	return val;
+}
+
+void
+reset_ATI_mach64_master(RegEntryIDPtr entryID)
+{
+	char				prop[MAX_STRING_PROP_SIZE];
+	UInt32				addrs_count;
+	UInt32				base;
+	OSStatus			err;
+	
+	get_string_property(entryID, "name", prop);
+	if (strncmp(prop, "ATY", 3))
+		return;
+	
+#if DEBUG
+	dt_printf(dct, "aty64: ");
+#endif
+
+	addrs_count = count_assigned_addresses(entryID);
+	switch(addrs_count) {
+		case 1:
+		case 2:
+		case 3:
+			err = get_logical_address(entryID, 16, (LogicalAddress *)&base, NULL);
+			break;
+		case 4:
+			err = get_logical_address(entryID, 20, (LogicalAddress *)&base, NULL);
+			break;
+		default:
+			dt_printf(dct, "aty64: bad address count !\n");
+			return;
+	}
+	if (!base || (err != noErr)) {
+		dt_printf(dct, "aty64: no address (err:%d) !\n", err);
+		return;
+	}
+		
+#if DEBUG
+	dt_printf(dct, "aty64: base = 0x%x\n", base);
+#endif
+
+	/* reset bus master */
+	ati_regw(base, ATI_BUS_CNTL, ati_regr(base, ATI_BUS_CNTL) | ATI_BUS_MSTR_RESET);
+
+	/* flush buffer, if bus mastering was memory <-> frame buffer */
+	ati_regw(base, ATI_BUS_CNTL, ati_regr(base, ATI_BUS_CNTL) | ATI_BUS_FLUSH_BUF);
+
+	/* reset graphic engine and clear errors, if bus mastering */
+	/* was memory -> command queue or HOST_DATA */
+	ati_regw(base, ATI_GEN_TEST_CNTL, ati_regr(base, ATI_GEN_TEST_CNTL) & ~ATI_GUI_ENGINE_ENABLE);
+	ati_regw(base, ATI_GEN_TEST_CNTL, ati_regr(base, ATI_GEN_TEST_CNTL) | ATI_GUI_ENGINE_ENABLE);
+
+	/* No effect for at least 3D RageLTPro, but an insurance. */
+	ati_regw(base, ATI_BUS_CNTL, ati_regr(base, ATI_BUS_CNTL) | ATI_BUS_HOST_ERR_ACK | ATI_BUS_FIFO_ERR_ACK);
+}
+	
+	
+static OSErr
+iterate_devices(iterate_device_proc	proc)
+{
+	RegEntryIter			iterator;
+	RegEntryIterationOp		operation;
+	unsigned long			address = 0;
+	OSStatus				err;
+	Boolean					done;
+	char					buffer[1024];
+	char*					namePtr;
+	
+	// Create an Iterator
+	operation = kRegIterRoot;	
+	err = RegistryEntryIterateCreate(&iterator);
+	
+	if (err == noErr) {
+		RegEntryID			entryID;
+		RegistryEntryIDInit(&entryID);
+		do {
+			RegPropertyValueSize pSize;
+			
+			done = false;
+			err = RegistryEntryIterate(	&iterator,
+										operation,
+										&entryID,
+										&done);
+			if (operation == kRegIterRoot)
+				operation = kRegIterDescendants;
+			else if (operation == kRegIterDescendants)
+				operation = kRegIterContinue;
+			if (!done && (err == noErr))
+				proc(&entryID);
+		} while (!done && (err == noErr));
+		RegistryEntryIDDispose(&entryID);
+	}
+	if (err != noErr)
+		dt_printf(dct, "iterate failed with error %d\n", err);
+	err = RegistryEntryIterateDispose(&iterator);
+	
+	return err;
+}

Added: trunk/miboot/src/pre_strap_ppc.exp
===================================================================
--- trunk/miboot/src/pre_strap_ppc.exp	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/pre_strap_ppc.exp	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1 @@
+ShutDownDevices

Added: trunk/miboot/src/processor.h
===================================================================
--- trunk/miboot/src/processor.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/processor.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,137 @@
+/* Modified version of Linux asm-ppc/processor.h */
+
+#ifndef __PPC_PROCESSOR_H__
+#define __PPC_PROCESSOR_H__
+
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_POW		(1<<18)		/* Enable Power Management */
+#define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
+#define MSR_ILE		(1<<16)		/* Interrupt Little-Endian enable */
+#define MSR_EE		(1<<15)		/* External Interrupt enable */
+#define MSR_PR		(1<<14)		/* Supervisor/User privilege */
+#define MSR_FP		(1<<13)		/* Floating Point enable */
+#define MSR_ME		(1<<12)		/* Machine Check enable */
+#define MSR_FE0		(1<<11)		/* Floating Exception mode 0 */
+#define MSR_SE		(1<<10)		/* Single Step */
+#define MSR_BE		(1<<9)		/* Branch Trace */
+#define MSR_FE1		(1<<8)		/* Floating Exception mode 1 */
+#define MSR_IP		(1<<6)		/* Exception prefix 0x000/0xFFF */
+#define MSR_IR		(1<<5)		/* Instruction MMU enable */
+#define MSR_DR		(1<<4)		/* Data MMU enable */
+#define MSR_RI		(1<<1)		/* Recoverable Exception */
+#define MSR_LE		(1<<0)		/* Little-Endian enable */
+
+/* Bit encodings for Hardware Implementation Register (HID0)
+   on PowerPC 603, 604, etc. processors (not 601). */
+#define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
+#define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
+#define HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
+#define HID0_SBCLK	(1<<27)
+#define HID0_EICE	(1<<26)
+#define HID0_ECLK	(1<<25)
+#define HID0_PAR	(1<<24)
+#define HID0_DOZE	(1<<23)
+#define HID0_NAP	(1<<22)
+#define HID0_SLEEP	(1<<21)
+#define HID0_DPM	(1<<20)
+#define HID0_ICE	(1<<15)		/* Instruction Cache Enable */
+#define HID0_DCE	(1<<14)		/* Data Cache Enable */
+#define HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
+#define HID0_DLOCK	(1<<12)		/* Data Cache Lock */
+#define HID0_ICFI	(1<<11)		/* Instruction Cache Flash Invalidate */
+#define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
+#define HID0_SIED	(1<<7)		/* Serial Instruction Execution [Disable] */
+#define HID0_BHTE	(1<<2)		/* Branch History Table Enable */
+#define HID0_BTCD	(1<<1)		/* Branch target cache disable */
+
+/* fpscr settings */
+#define FPSCR_FX        (1<<31)
+#define FPSCR_FEX       (1<<30)
+
+#define	TBRU	269	/* Time base Upper/Lower (Reading) */
+#define	TBRL	268
+#define TBWU	284	/* Time base Upper/Lower (Writing) */
+#define TBWL	285
+#define	XER	1
+#define LR	8
+#define CTR	9
+#define HID0	1008	/* Hardware Implementation */
+#define PVR	287	/* Processor Version */
+#define IBAT0U	528	/* Instruction BAT #0 Upper/Lower */
+#define IBAT0L	529
+#define IBAT1U	530	/* Instruction BAT #1 Upper/Lower */
+#define IBAT1L	531
+#define IBAT2U	532	/* Instruction BAT #2 Upper/Lower */
+#define IBAT2L	533
+#define IBAT3U	534	/* Instruction BAT #3 Upper/Lower */
+#define IBAT3L	535
+#define DBAT0U	536	/* Data BAT #0 Upper/Lower */
+#define DBAT0L	537
+#define DBAT1U	538	/* Data BAT #1 Upper/Lower */
+#define DBAT1L	539
+#define DBAT2U	540	/* Data BAT #2 Upper/Lower */
+#define DBAT2L	541
+#define DBAT3U	542	/* Data BAT #3 Upper/Lower */
+#define DBAT3L	543
+#define DMISS	976	/* TLB Lookup/Refresh registers */
+#define DCMP	977
+#define HASH1	978
+#define HASH2	979
+#define IMISS	980
+#define ICMP	981
+#define RPA	982
+#define SDR1	25	/* MMU hash base register */
+#define DAR	19	/* Data Address Register */
+#define SPR0	272	/* Supervisor Private Registers */
+#define SPRG0   272
+#define SPR1	273
+#define SPRG1   273
+#define SPR2	274
+#define SPRG2   274
+#define SPR3	275
+#define SPRG3   275
+#define DSISR	18
+#define SRR0	26	/* Saved Registers (exception) */
+#define SRR1	27
+#define IABR	1010	/* Instruction Address Breakpoint */
+#define DEC	22	/* Decrementer */
+#define EAR	282	/* External Address Register */
+#define L2CR	1017    /* PPC 750 L2 control register */
+
+#define THRM1	1020
+#define THRM2	1021
+#define THRM3	1022
+#define THRM1_TIN 0x1
+#define THRM1_TIV 0x2
+#define THRM1_THRES (0x7f<<2)
+#define THRM1_TID (1<<29)
+#define THRM1_TIE (1<<30)
+#define THRM1_V   (1<<31)
+#define THRM3_E   (1<<31)
+
+/* Segment Registers */
+#define SR0	0
+#define SR1	1
+#define SR2	2
+#define SR3	3
+#define SR4	4
+#define SR5	5
+#define SR6	6
+#define SR7	7
+#define SR8	8
+#define SR9	9
+#define SR10	10
+#define SR11	11
+#define SR12	12
+#define SR13	13
+#define SR14	14
+#define SR15	15
+  
+#endif /* __PPC_PROCESSOR_H__ */
+
+
+
+
+
+
+

Added: trunk/miboot/src/rs6000.h
===================================================================
--- trunk/miboot/src/rs6000.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/rs6000.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,244 @@
+/* IBM RS/6000 "XCOFF" file definitions for BFD.
+   Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+   FIXME: Can someone provide a transliteration of this name into ASCII?
+   Using the following chars caused a compiler warning on HIUX (so I replaced
+   them with octal escapes), and isn't useful without an understanding of what
+   character set it is.
+   Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+   and John Gilmore of Cygnus Support.  */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+	char f_magic[2];	/* magic number			*/
+	char f_nscns[2];	/* number of sections		*/
+	char f_timdat[4];	/* time & date stamp		*/
+	char f_symptr[4];	/* file pointer to symtab	*/
+	char f_nsyms[4];	/* number of symtab entries	*/
+	char f_opthdr[2];	/* sizeof(optional hdr)		*/
+	char f_flags[2];	/* flags			*/
+};
+
+        /* IBM RS/6000 */
+
+#define U802WRMAGIC		0730
+#define U802ROMAGIC		0735
+#define U802TOCMAGIC	0737
+
+#define BADMAG(x)	\
+	((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
+	 (x).f_magic != U802TOCMAGIC)
+
+#define	FILHDR	struct external_filehdr
+#define	FILHSZ	20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct 
+{
+  unsigned char	magic[2];	/* type of file			*/
+  unsigned char	vstamp[2];	/* version stamp		*/
+  unsigned char	tsize[4];	/* text size in bytes, padded to FW bdry */
+  unsigned char	dsize[4];	/* initialized data "  "	*/
+  unsigned char	bsize[4];	/* uninitialized data "   "	*/
+  unsigned char	entry[4];	/* entry pt.			*/
+  unsigned char	text_start[4];	/* base of text used for this file */
+  unsigned char	data_start[4];	/* base of data used for this file */
+  unsigned char	o_toc[4];	/* address of TOC */
+  unsigned char	o_snentry[2];	/* section number of entry point */
+  unsigned char	o_sntext[2];	/* section number of .text section */
+  unsigned char	o_sndata[2];	/* section number of .data section */
+  unsigned char	o_sntoc[2];	/* section number of TOC */
+  unsigned char	o_snloader[2];	/* section number of .loader section */
+  unsigned char	o_snbss[2];	/* section number of .bss section */
+  unsigned char	o_algntext[2];	/* .text alignment */
+  unsigned char	o_algndata[2];	/* .data alignment */
+  unsigned char	o_modtype[2];	/* module type (??) */
+  unsigned char o_cputype[2];	/* cpu type */
+  unsigned char	o_maxstack[4];	/* max stack size (??) */
+  unsigned char o_maxdata[4];	/* max data size (??) */
+  unsigned char	o_resv2[12];	/* reserved */
+}
+AOUTHDR;
+
+#define AOUTSZ 72
+#define SMALL_AOUTSZ (28)
+#define AOUTHDRSZ 72
+
+#define	RS6K_AOUTHDR_OMAGIC	0x0107	/* old: text & data writeable */
+#define	RS6K_AOUTHDR_NMAGIC	0x0108	/* new: text r/o, data r/w */
+#define	RS6K_AOUTHDR_ZMAGIC	0x010B	/* paged: text r/o, both page-aligned */
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+	char		s_name[8];	/* section name			*/
+	char		s_paddr[4];	/* physical address, aliased s_nlib */
+	char		s_vaddr[4];	/* virtual address		*/
+	char		s_size[4];	/* section size			*/
+	char		s_scnptr[4];	/* file ptr to raw data for section */
+	char		s_relptr[4];	/* file ptr to relocation	*/
+	char		s_lnnoptr[4];	/* file ptr to line numbers	*/
+	char		s_nreloc[2];	/* number of relocation entries	*/
+	char		s_nlnno[2];	/* number of line number entries*/
+	char		s_flags[4];	/* flags			*/
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT	".text"
+#define _DATA	".data"
+#define _BSS	".bss"
+#define _PAD	".pad"
+#define _LOADER	".loader"
+
+#define	SCNHDR	struct external_scnhdr
+#define	SCNHSZ	40
+
+/* XCOFF uses a special .loader section with type STYP_LOADER.  */
+#define STYP_LOADER 0x1000
+
+/* XCOFF uses a special .debug section with type STYP_DEBUG.  */
+#define STYP_DEBUG 0x2000
+
+/* XCOFF handles line number or relocation overflow by creating
+   another section header with STYP_OVRFLO set.  */
+#define STYP_OVRFLO 0x8000
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+	union {
+		char l_symndx[4];	/* function name symbol index, iff l_lnno == 0*/
+		char l_paddr[4];	/* (physical) address of line number	*/
+	} l_addr;
+	char l_lnno[2];	/* line number		*/
+};
+
+
+#define	LINENO	struct external_lineno
+#define	LINESZ	6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN	8	/* # characters in a symbol name	*/
+#define E_FILNMLEN	14	/* # characters in a file name		*/
+#define E_DIMNUM	4	/* # array dimensions in auxiliary entry */
+
+struct external_syment 
+{
+  union {
+    char e_name[E_SYMNMLEN];
+    struct {
+      char e_zeroes[4];
+      char e_offset[4];
+    } e;
+  } e;
+  char e_value[4];
+  char e_scnum[2];
+  char e_type[2];
+  char e_sclass[1];
+  char e_numaux[1];
+};
+
+
+
+#define N_BTMASK	(017)
+#define N_TMASK		(060)
+#define N_BTSHFT	(4)
+#define N_TSHIFT	(2)
+  
+
+union external_auxent {
+	struct {
+		char x_tagndx[4];	/* str, un, or enum tag indx */
+		union {
+			struct {
+			    char  x_lnno[2]; /* declaration line number */
+			    char  x_size[2]; /* str/union/array size */
+			} x_lnsz;
+			char x_fsize[4];	/* size of function */
+		} x_misc;
+		union {
+			struct {		/* if ISFCN, tag, or .bb */
+			    char x_lnnoptr[4];	/* ptr to fcn line # */
+			    char x_endndx[4];	/* entry ndx past block end */
+			} x_fcn;
+			struct {		/* if ISARY, up to 4 dimen. */
+			    char x_dimen[E_DIMNUM][2];
+			} x_ary;
+		} x_fcnary;
+		char x_tvndx[2];		/* tv index */
+	} x_sym;
+
+	union {
+		char x_fname[E_FILNMLEN];
+		struct {
+			char x_zeroes[4];
+			char x_offset[4];
+		} x_n;
+	} x_file;
+
+	struct {
+		char x_scnlen[4];			/* section length */
+		char x_nreloc[2];	/* # relocation entries */
+		char x_nlinno[2];	/* # line numbers */
+	} x_scn;
+
+        struct {
+		char x_tvfill[4];	/* tv fill value */
+		char x_tvlen[2];	/* length of .tv */
+		char x_tvran[2][2];	/* tv range */
+	} x_tv;		/* info about .tv section (in auxent of symbol .tv)) */
+
+	struct {
+		unsigned char x_scnlen[4];
+		unsigned char x_parmhash[4];
+		unsigned char x_snhash[2];
+		unsigned char x_smtyp[1];
+		unsigned char x_smclas[1];
+		unsigned char x_stab[4];
+		unsigned char x_snstab[2];
+	} x_csect;
+
+};
+
+#define	SYMENT	struct external_syment
+#define	SYMESZ	18	
+#define	AUXENT	union external_auxent
+#define	AUXESZ	18
+#define DBXMASK 0x80		/* for dbx storage mask */
+#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_size[1];
+  char r_type[1];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+#define DEFAULT_DATA_SECTION_ALIGNMENT 4
+#define DEFAULT_BSS_SECTION_ALIGNMENT 4
+#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
+/* For new sections we havn't heard of before */
+#define DEFAULT_SECTION_ALIGNMENT 4

Added: trunk/miboot/src/test_paint.c
===================================================================
--- trunk/miboot/src/test_paint.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/test_paint.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,30 @@
+#include <Types.h>
+#include <Memory.h>
+#include <Quickdraw.h>
+#include <Fonts.h>
+#include <Events.h>
+#include <Menus.h>
+#include <Errors.h>
+#include <Files.h>
+#include <Devices.h>
+#include <Windows.h>
+
+void test_paint(void)
+{
+	GDHandle	hdl;
+	PixMapPtr	pm;
+	UInt32		x,y;
+	
+	hdl = LMGetMainDevice();
+	if (hdl == NULL || (**hdl).gdPMap == NULL)
+		return;
+	pm = *(**hdl).gdPMap;
+	if (pm->baseAddr == NULL)
+		return;
+	
+	for(y=100; y<200; y++) {
+		unsigned char* line = (unsigned char*)pm->baseAddr + y * (pm->rowBytes & 0x3fff);
+		for (x=100; x<500; x++)
+			line[x] = 0;
+	}
+}

Added: trunk/miboot/src/uLibc.c
===================================================================
--- trunk/miboot/src/uLibc.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/uLibc.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,39 @@
+#include <Types.h>
+#include <Memory.h>
+#include <OSUtils.h>
+
+#include "uLibc.h"
+
+UInt32 strlen(char * s) {
+	char *sc;
+	for (sc = s; *sc != '\0'; ++sc) ;
+	return sc - s;
+}
+void memset(void *p, int c, UInt32 s) {
+	while(s--)
+		((char *)p)[s] = (char)c;
+}
+void memcpy(void* d, void* s, UInt32 z) {
+	BlockMove(s,d,z); /* BlockMoveData ? */
+}
+void memmove(void* d, void* s, UInt32 z) {
+	BlockMove(s,d,z); /* BlockMoveData ? */
+}
+int strcmp(char * cs,char * ct) {
+	char __res;
+	while (1) {
+		if ((__res = *cs - *ct++) != 0 || !*cs++)
+			break;
+	}
+	return __res;
+}
+char * strcat(char * dest, char * src) {
+	char *tmp = dest;
+	while (*dest) dest++;
+	while ((*dest++ = *src++) != '\0') ;
+	return tmp;
+}
+void strcpy(char * dest, char * src) {
+	BlockMove(src, dest, strlen(src)+1);
+}
+

Added: trunk/miboot/src/uLibc.h
===================================================================
--- trunk/miboot/src/uLibc.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/uLibc.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,14 @@
+#ifndef __U_LIBC_H__
+#define __U_LIBC_H__
+
+extern UInt32 strlen(char * s);
+extern void memset(void *p, int c, UInt32 s);
+extern void memcpy(void* d, void* s, UInt32 z);
+extern void memmove(void* d, void* s, UInt32 z);
+extern int strcmp( char * cs, char * ct);
+extern char * strcat(char * dest,  char * src);
+extern void strcpy(char * dest,  char * src);
+
+
+
+#endif

Added: trunk/miboot/src/zlib.c
===================================================================
--- trunk/miboot/src/zlib.c	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/zlib.c	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,2155 @@
+/*
+ * 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.2.1 1999/05/29 19:09:42 cort 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 */
+
+#undef Byte
+
+#include <Types.h>
+#include <OSUtils.h>
+#include <Memory.h>
+
+#define Byte zlib_Byte
+
+#define zmemcpy(d,s,z) BlockMove((s),(d),(z))
+#define zmemzero(dest, len)	do {int __l=len;while(__l--) ((char *)(dest))[__l]=0;} while(0)
+
+/* 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;
+}

Added: trunk/miboot/src/zlib.h
===================================================================
--- trunk/miboot/src/zlib.h	2006-07-31 16:08:48 UTC (rev 156)
+++ trunk/miboot/src/zlib.h	2006-08-06 10:53:03 UTC (rev 157)
@@ -0,0 +1,436 @@
+/*	$Id: zlib.h,v 1.1 1997/07/31 07:16:15 paulus 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 at prep.ai.mit.edu    madler at alumni.caltech.edu
+ */
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#define Byte zlib_Byte
+
+/* #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
+
+#undef Byte
+
+#endif /* _ZLIB_H */




More information about the Debootloaders-devel mailing list