[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(¶m, 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 **)¶m.csParam[0]) = &hwGetEntry;
+ err = PBStatusSync((ParmBlkPtr)¶m);
+ 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(¶m, 0, sizeof(CntrlParam));
+ memset(&hwModeSet, 0, sizeof(VDPageInfo));
+ memset(&hwModeGet, 0, sizeof(VDSwitchInfoRec));
+
+
+ param.csCode = cscGetCurMode;
+ param.ioCRefNum = (**gDevice).gdRefNum;
+ *((VDSwitchInfoRec **)¶m.csParam[0]) = &hwModeGet;
+ err = PBStatusSync((ParmBlkPtr)¶m);
+ 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 **)¶m.csParam[0]) = &hwVideoParams;
+ err = PBStatusSync((ParmBlkPtr)¶m);
+ 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 **)¶m.csParam[0]) = &hwModeSet;
+ err = PBControlSync((ParmBlkPtr)¶m);
+ 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(¶m, 0, sizeof(CntrlParam));
+ memset(&hwCursQuery, 0, sizeof(VDSupportsHardwareCursorRec));
+ memset(&hwCursSet, 0, sizeof(VDDrawHardwareCursorRec));
+ param.csCode = cscSupportsHardwareCursor;
+ param.ioCRefNum = driverRefNum;
+ *((VDSupportsHardwareCursorRec **)¶m.csParam[0]) = &hwCursQuery;
+ err = PBStatusSync((ParmBlkPtr)¶m);
+ if (err != noErr)
+ return;
+
+ if (!hwCursQuery.csSupportsHardwareCursor)
+ return;
+
+ memset(¶m, 0, sizeof(CntrlParam));
+ memset(&hwCursSet, 0, sizeof(VDDrawHardwareCursorRec));
+ param.csCode = cscDrawHardwareCursor;
+ param.ioCRefNum = driverRefNum;
+ *((VDDrawHardwareCursorRec **)¶m.csParam[0]) = &hwCursSet;
+ err = PBControlSync((ParmBlkPtr)¶m);
+}
+
+// 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(¶m, 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 **)¶m.csParam[0]) = &hwSetEntry;
+ err = PBControlSync((ParmBlkPtr)¶m);
+
+ 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 **)¶m.csParam[0]) = &hwSetEntry;
+ err = PBControlSync((ParmBlkPtr)¶m);
+
+ 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(®List, 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