From 5ee58eeda7055d3502f1c903d7bb6bd9c40150af Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 10 Nov 2003 06:08:40 +0000 Subject: [PATCH] Fully synchronize sys/boot from FreeBSD-5.x, but add / to the module path so /kernel will be found and loaded instead of /boot/kernel. This will give us all the capabilities of the FreeBSD-5 boot code including AMD64 and ELF64 support. As part of this work, rather then try to adjust ufs/fs.h and friends to get UFS2 info I instead copied the fs.h and friends from FreeBSD-5 into the sys/boot subtree Additionally, import Peter Wemm's linker set improvements from FreeBSD-5.x. They happen to be compatible with GCC 2.95.x and it allows very few changes to be made to the boot code. NOTE! UFS2 support is not enabled by default as of this commit because it causes boot2 to run over its limit by 88 bytes. --- sys/boot/Makefile | 25 +- sys/boot/README | 4 +- sys/boot/alpha/Makefile | 2 +- sys/boot/alpha/Makefile.inc | 4 +- sys/boot/alpha/boot1/Makefile | 13 +- sys/boot/alpha/boot1/boot1.c | 70 +- sys/boot/alpha/boot1/sys.c | 257 -- sys/boot/alpha/cdboot/Makefile | 8 +- sys/boot/alpha/cdboot/cdboot-4.0R.gz.uu | 1555 --------- sys/boot/alpha/cdboot/version | 6 +- sys/boot/alpha/common/Makefile.common | 27 +- sys/boot/alpha/common/conf.c | 10 +- sys/boot/alpha/common/main.c | 4 +- sys/boot/alpha/libalpha/Makefile | 5 +- sys/boot/alpha/libalpha/OSFpal.c | 4 +- sys/boot/alpha/libalpha/alpha_copy.c | 4 +- sys/boot/alpha/libalpha/alpha_module.c | 2 +- sys/boot/alpha/libalpha/bbinfo.h | 4 +- sys/boot/alpha/libalpha/bootinfo.c | 43 +- sys/boot/alpha/libalpha/common.h | 16 +- sys/boot/alpha/libalpha/delay.c | 2 +- sys/boot/alpha/libalpha/devicename.c | 2 +- sys/boot/alpha/libalpha/elf_freebsd.c | 28 +- sys/boot/alpha/libalpha/getsecs.c | 4 +- sys/boot/alpha/libalpha/libalpha.h | 6 +- sys/boot/alpha/libalpha/pal.S | 4 +- sys/boot/alpha/libalpha/prom.c | 8 +- sys/boot/alpha/libalpha/prom_disp.S | 4 +- sys/boot/alpha/libalpha/prom_swpal.S | 4 +- sys/boot/alpha/libalpha/reboot.c | 2 +- sys/boot/alpha/libalpha/srmdisk.c | 13 +- sys/boot/alpha/libalpha/srmnet.c | 4 +- sys/boot/alpha/libalpha/start.S | 4 +- sys/boot/alpha/libalpha/time.c | 2 +- sys/boot/alpha/loader/Makefile | 6 +- sys/boot/alpha/loader/version | 6 +- sys/boot/alpha/netboot/Makefile | 8 +- sys/boot/alpha/netboot/version | 9 +- sys/boot/arc/Makefile | 2 +- sys/boot/arc/Makefile.inc | 4 +- sys/boot/arc/include/arcfuncs.h | 3 +- sys/boot/arc/include/arctypes.h | 3 +- sys/boot/arc/include/libarc.h | 5 +- sys/boot/arc/lib/Makefile | 5 +- sys/boot/arc/lib/abort.c | 2 +- sys/boot/arc/lib/arcconsole.c | 8 +- sys/boot/arc/lib/arcdisk.c | 14 +- sys/boot/arc/lib/arch/alpha/copy.c | 2 +- sys/boot/arc/lib/arch/alpha/rpb.c | 2 +- sys/boot/arc/lib/arch/alpha/setjmp.S | 5 +- sys/boot/arc/lib/arch/alpha/start.S | 3 +- sys/boot/arc/lib/bootinfo.c | 37 +- sys/boot/arc/lib/delay.c | 2 +- sys/boot/arc/lib/devicename.c | 5 +- sys/boot/arc/lib/elf_freebsd.c | 26 +- sys/boot/arc/lib/module.c | 2 +- sys/boot/arc/lib/prom.c | 3 +- sys/boot/arc/lib/setjmperr.c | 2 +- sys/boot/arc/lib/time.c | 2 +- sys/boot/arc/loader/Makefile | 19 +- sys/boot/arc/loader/conf.c | 10 +- sys/boot/arc/loader/main.c | 2 +- sys/boot/arc/loader/version | 2 +- sys/boot/common/Makefile.inc | 21 +- sys/boot/common/bcache.c | 117 +- sys/boot/common/boot.c | 74 +- sys/boot/common/bootstrap.h | 129 +- sys/boot/common/commands.c | 7 +- sys/boot/common/console.c | 4 +- sys/boot/common/dev_net.c | 42 +- sys/boot/common/dev_net.h | 2 +- sys/boot/common/devopen.c | 5 +- sys/boot/common/dinode.h | 171 + sys/boot/common/fs.h | 604 ++++ sys/boot/common/help.common | 47 +- sys/boot/common/interp.c | 7 +- sys/boot/common/interp_backslash.c | 8 +- sys/boot/common/interp_forth.c | 23 +- sys/boot/common/interp_parse.c | 8 +- sys/boot/common/isapnp.c | 6 +- sys/boot/common/isapnp.h | 8 +- sys/boot/common/load.c | 5 +- sys/boot/common/load_aout.c | 262 -- sys/boot/common/load_elf.c | 491 ++- sys/boot/common/load_elf32.c | 8 + sys/boot/common/load_elf64.c | 8 + sys/boot/common/loader.8 | 84 +- sys/boot/common/ls.c | 14 +- sys/boot/common/merge_help.awk | 6 +- sys/boot/common/misc.c | 4 +- sys/boot/common/module.c | 877 +++-- sys/boot/common/newvers.sh | 6 +- sys/boot/common/panic.c | 13 +- sys/boot/common/pnp.c | 33 +- sys/boot/common/pnpdata | 5 +- sys/boot/common/ufsread.c | 271 ++ sys/boot/efi/Makefile | 6 + sys/boot/efi/Makefile.inc | 5 + sys/boot/efi/include/README | 36 + sys/boot/efi/include/efi.h | 52 + sys/boot/efi/include/efi_nii.h | 85 + sys/boot/efi/include/efiapi.h | 707 ++++ sys/boot/efi/include/eficon.h | 302 ++ sys/boot/efi/include/efidebug.h | 108 + sys/boot/efi/include/efidef.h | 196 ++ sys/boot/efi/include/efidevp.h | 394 +++ sys/boot/efi/include/efierr.h | 63 + sys/boot/efi/include/efifpswa.h | 43 + sys/boot/efi/include/efifs.h | 119 + .../{arc/lib/time.c => efi/include/efilib.h} | 27 +- sys/boot/efi/include/efinet.h | 264 ++ sys/boot/efi/include/efipart.h | 61 + sys/boot/efi/include/efiprot.h | 554 ++++ sys/boot/efi/include/efipxebc.h | 462 +++ sys/boot/efi/include/efiser.h | 135 + sys/boot/efi/include/efistdarg.h | 35 + sys/boot/efi/include/i386/efibind.h | 252 ++ sys/boot/efi/include/i386/pe.h | 595 ++++ sys/boot/efi/include/ia64/efibind.h | 153 + sys/boot/efi/include/ia64/pe.h | 601 ++++ sys/boot/efi/libefi/Makefile | 40 + sys/boot/efi/libefi/arch/ia64/ldscript.ia64 | 76 + sys/boot/efi/libefi/arch/ia64/start.S | 306 ++ .../{pc32/libi386 => efi/libefi}/bootinfo.c | 222 +- .../alpha_copy.c => efi/libefi/copy.c} | 45 +- sys/boot/{arc/lib => efi/libefi}/delay.c | 23 +- sys/boot/efi/libefi/devicename.c | 241 ++ .../devopen.c => efi/libefi/efi_console.c} | 85 +- .../libalpha.h => efi/libefi/efiboot.h} | 84 +- .../i386_module.c => efi/libefi/efifpswa.c} | 45 +- sys/boot/efi/libefi/efifs.c | 402 +++ sys/boot/efi/libefi/efinet.c | 268 ++ .../libalpha => efi/libefi}/elf_freebsd.c | 197 +- sys/boot/efi/libefi/libefi.c | 187 ++ .../{common/dev_net.h => efi/libefi/module.c} | 16 +- sys/boot/efi/libefi/time.c | 222 ++ sys/boot/efi/loader/Makefile | 124 + sys/boot/{arc => efi}/loader/conf.c | 51 +- sys/boot/efi/loader/main.c | 562 ++++ sys/boot/efi/loader/version | 17 + sys/boot/ficl/Makefile | 59 +- sys/boot/ficl/alpha/sysdep.c | 6 +- sys/boot/ficl/alpha/sysdep.h | 224 +- sys/boot/ficl/dict.c | 177 +- sys/boot/ficl/ficl.c | 450 ++- sys/boot/ficl/ficl.h | 563 +++- sys/boot/ficl/fileaccess.c | 428 +++ sys/boot/ficl/float.c | 1067 ++++++ sys/boot/ficl/i386/sysdep.c | 6 +- sys/boot/ficl/i386/sysdep.h | 224 +- sys/boot/ficl/{alpha => ia64}/sysdep.c | 6 +- sys/boot/ficl/{alpha => ia64}/sysdep.h | 226 +- sys/boot/ficl/loader.c | 475 ++- sys/boot/ficl/math64.c | 49 +- sys/boot/ficl/math64.h | 54 +- sys/boot/ficl/prefix.c | 202 ++ sys/boot/ficl/search.c | 396 +++ sys/boot/ficl/softwords/classes.fr | 34 +- sys/boot/ficl/softwords/ficlclass.fr | 87 + sys/boot/ficl/softwords/ficllocal.fr | 2 +- sys/boot/ficl/softwords/fileaccess.fr | 27 + sys/boot/ficl/softwords/forml.fr | 76 + sys/boot/ficl/softwords/freebsd.fr | 2 +- sys/boot/ficl/softwords/ifbrack.fr | 24 +- sys/boot/ficl/softwords/jhlocal.fr | 24 +- sys/boot/ficl/softwords/marker.fr | 3 + sys/boot/ficl/softwords/oo.fr | 481 ++- sys/boot/ficl/softwords/prefix.fr | 60 + sys/boot/ficl/softwords/softcore.awk | 15 +- sys/boot/ficl/softwords/softcore.fr | 118 +- sys/boot/ficl/softwords/string.fr | 136 +- sys/boot/ficl/{alpha => sparc64}/sysdep.c | 6 +- sys/boot/ficl/{alpha => sparc64}/sysdep.h | 194 +- sys/boot/ficl/stack.c | 73 +- sys/boot/ficl/testmain.c | 94 +- sys/boot/ficl/tools.c | 909 ++++++ sys/boot/ficl/unix.c | 26 + sys/boot/ficl/vm.c | 217 +- sys/boot/ficl/words.c | 2875 ++++++++--------- sys/boot/forth/beastie.4th | 256 ++ sys/boot/forth/frames.4th | 91 + sys/boot/forth/fred.4th | 256 ++ sys/boot/forth/loader.4th | 183 +- sys/boot/forth/loader.4th.8 | 52 +- sys/boot/forth/loader.conf | 165 +- sys/boot/forth/loader.conf.5 | 17 +- sys/boot/forth/loader.rc | 2 +- sys/boot/forth/pnp.4th | 173 + sys/boot/forth/screen.4th | 37 + sys/boot/forth/support.4th | 642 +++- sys/boot/i386/Makefile | 4 +- sys/boot/i386/Makefile.inc | 17 +- sys/boot/i386/boot0/Makefile | 31 +- sys/boot/i386/boot0/boot0.S | 14 +- sys/boot/i386/boot0/boot0.s | 14 +- sys/boot/i386/boot2/Makefile | 71 +- sys/boot/i386/boot2/boot1.S | 653 ++-- sys/boot/i386/boot2/boot1.s | 653 ++-- sys/boot/i386/boot2/boot2.c | 478 +-- sys/boot/i386/boot2/lib.h | 2 +- sys/boot/i386/boot2/sio.S | 2 +- sys/boot/i386/boot2/sio.s | 2 +- sys/boot/i386/btx/Makefile | 2 +- sys/boot/i386/btx/Makefile.inc | 3 + sys/boot/i386/btx/btx/Makefile | 18 +- sys/boot/i386/btx/btx/btx.S | 117 +- sys/boot/i386/btx/btx/btx.s | 117 +- sys/boot/i386/btx/btxldr/Makefile | 10 +- sys/boot/i386/btx/btxldr/btxldr.s | 6 +- sys/boot/i386/btx/lib/Makefile | 11 +- sys/boot/i386/btx/lib/btxcsu.S | 2 +- sys/boot/i386/btx/lib/btxcsu.s | 2 +- sys/boot/i386/btx/lib/btxsys.S | 2 +- sys/boot/i386/btx/lib/btxsys.s | 2 +- sys/boot/i386/btx/lib/btxv86.S | 2 +- sys/boot/i386/btx/lib/btxv86.h | 2 +- sys/boot/i386/btx/lib/btxv86.s | 2 +- sys/boot/i386/cdboot/Makefile | 9 +- sys/boot/i386/cdboot/cdboot.S | 4 +- sys/boot/i386/cdboot/cdboot.s | 4 +- sys/boot/i386/kgzldr/Makefile | 29 +- sys/boot/i386/kgzldr/boot.c | 6 +- sys/boot/i386/kgzldr/crt.s | 4 +- sys/boot/i386/kgzldr/kgzldr.h | 2 +- sys/boot/i386/kgzldr/lib.c | 6 +- sys/boot/i386/kgzldr/sio.s | 10 +- sys/boot/i386/kgzldr/start.s | 4 +- sys/boot/i386/libi386/Makefile | 28 +- sys/boot/i386/libi386/amd64_tramp.S | 114 + sys/boot/i386/libi386/biosacpi.c | 130 + sys/boot/i386/libi386/bioscd.c | 17 +- sys/boot/i386/libi386/biosdisk.c | 206 +- sys/boot/i386/libi386/biosmem.c | 7 +- sys/boot/i386/libi386/biospci.c | 4 +- sys/boot/i386/libi386/biospnp.c | 53 +- sys/boot/i386/libi386/biossmap.c | 108 + sys/boot/i386/libi386/bootinfo.c | 216 +- .../bootinfo.c => i386/libi386/bootinfo32.c} | 316 +- sys/boot/i386/libi386/bootinfo64.c | 208 ++ sys/boot/i386/libi386/comconsole.c | 27 +- sys/boot/i386/libi386/devicename.c | 4 +- .../{elf_freebsd.c => elf32_freebsd.c} | 36 +- .../{elf_freebsd.c => elf64_freebsd.c} | 80 +- sys/boot/i386/libi386/gatea20.c | 6 +- sys/boot/i386/libi386/i386_copy.c | 4 +- sys/boot/i386/libi386/i386_module.c | 23 +- sys/boot/i386/libi386/libi386.h | 14 +- sys/boot/i386/libi386/nullconsole.c | 9 +- sys/boot/i386/libi386/pread.c | 8 +- sys/boot/i386/libi386/pxe.c | 20 +- sys/boot/i386/libi386/pxe.h | 8 +- sys/boot/i386/libi386/pxetramp.s | 10 +- sys/boot/i386/libi386/time.c | 5 +- sys/boot/i386/libi386/vidconsole.c | 458 +-- sys/boot/i386/loader/Makefile | 48 +- sys/boot/i386/loader/conf.c | 14 +- sys/boot/i386/loader/help.i386 | 19 + sys/boot/i386/loader/loader.rc | 21 + sys/boot/i386/loader/main.c | 18 +- sys/boot/i386/loader/version | 6 +- sys/boot/i386/mbr/Makefile | 9 +- sys/boot/i386/mbr/mbr.s | 4 +- sys/boot/i386/pxeldr/Makefile | 35 +- sys/boot/i386/pxeldr/pxeboot.8 | 21 +- sys/boot/i386/pxeldr/pxeldr.S | 9 +- sys/boot/i386/pxeldr/pxeldr.s | 9 +- sys/boot/ia64/Makefile | 6 + sys/boot/ia64/Makefile.inc | 5 + sys/boot/ia64/libski/Makefile | 37 + sys/boot/ia64/libski/acpi_stub.c | 194 ++ .../{pc32/libi386 => ia64/libski}/bootinfo.c | 189 +- .../alpha_copy.c => ia64/libski/copy.c} | 31 +- .../{common/dev_net.h => ia64/libski/delay.c} | 12 +- sys/boot/ia64/libski/devicename.c | 238 ++ sys/boot/ia64/libski/efi_stub.c | 268 ++ .../libalpha => ia64/libski}/elf_freebsd.c | 178 +- .../{common/dev_net.h => ia64/libski/exit.c} | 18 +- sys/boot/ia64/libski/libski.h | 97 + sys/boot/{arc/lib => ia64/libski}/module.c | 19 +- .../alpha_module.c => ia64/libski/pal_stub.S} | 72 +- sys/boot/ia64/libski/sal_stub.c | 118 + .../devopen.c => ia64/libski/skiconsole.c} | 81 +- sys/boot/ia64/libski/skifs.c | 193 ++ .../alpha_module.c => ia64/libski/ssc.c} | 38 +- sys/boot/ia64/libski/time.c | 174 + sys/boot/ia64/skiload/Makefile | 86 + sys/boot/{arc/loader => ia64/skiload}/conf.c | 40 +- sys/boot/ia64/skiload/ldscript.ia64 | 64 + sys/boot/ia64/skiload/main.c | 128 + sys/boot/ia64/skiload/skiload.cmd | 17 + .../probe_keyboard.c => ia64/skiload/start.S} | 59 +- sys/boot/ia64/skiload/version | 9 + sys/boot/ofw/Makefile | 6 + sys/boot/ofw/common/Makefile.inc | 4 + sys/boot/ofw/common/main.c | 163 + sys/boot/ofw/libofw/Makefile | 33 + sys/boot/ofw/libofw/devicename.c | 127 + .../devopen.c => ofw/libofw/elf_freebsd.c} | 75 +- sys/boot/ofw/libofw/libofw.h | 74 + sys/boot/ofw/libofw/ofw_console.c | 127 + sys/boot/ofw/libofw/ofw_copy.c | 111 + sys/boot/ofw/libofw/ofw_disk.c | 127 + sys/boot/ofw/libofw/ofw_memory.c | 101 + .../lib/module.c => ofw/libofw/ofw_module.c} | 12 +- sys/boot/ofw/libofw/ofw_net.c | 261 ++ .../dev_net.h => ofw/libofw/ofw_reboot.c} | 20 +- .../libalpha/time.c => ofw/libofw/ofw_time.c} | 47 +- sys/boot/ofw/libofw/openfirm.c | 943 ++++++ sys/boot/ofw/libofw/openfirm.h | 129 + sys/boot/pc32/Makefile | 4 +- sys/boot/pc32/Makefile.inc | 17 +- sys/boot/pc32/boot0/Makefile | 31 +- sys/boot/pc32/boot0/boot0.S | 14 +- sys/boot/pc32/boot2/Makefile | 71 +- sys/boot/pc32/boot2/boot1.S | 653 ++-- sys/boot/pc32/boot2/boot2.c | 478 +-- sys/boot/pc32/boot2/lib.h | 2 +- sys/boot/pc32/boot2/sio.S | 2 +- sys/boot/pc32/btx/Makefile | 2 +- sys/boot/pc32/btx/Makefile.inc | 3 + sys/boot/pc32/btx/btx/Makefile | 18 +- sys/boot/pc32/btx/btx/btx.S | 117 +- sys/boot/pc32/btx/btxldr/Makefile | 10 +- sys/boot/pc32/btx/lib/Makefile | 11 +- sys/boot/pc32/btx/lib/btxcsu.S | 2 +- sys/boot/pc32/btx/lib/btxsys.S | 2 +- sys/boot/pc32/btx/lib/btxv86.S | 2 +- sys/boot/pc32/btx/lib/btxv86.h | 2 +- sys/boot/pc32/cdboot/Makefile | 9 +- sys/boot/pc32/cdboot/cdboot.S | 4 +- sys/boot/pc32/kgzldr/Makefile | 29 +- sys/boot/pc32/kgzldr/boot.c | 6 +- sys/boot/pc32/kgzldr/crt.s | 4 +- sys/boot/pc32/kgzldr/kgzldr.h | 2 +- sys/boot/pc32/kgzldr/lib.c | 6 +- sys/boot/pc32/kgzldr/sio.s | 10 +- sys/boot/pc32/kgzldr/start.s | 4 +- sys/boot/pc32/libi386/Makefile | 28 +- sys/boot/pc32/libi386/amd64_tramp.S | 114 + sys/boot/pc32/libi386/biosacpi.c | 130 + sys/boot/pc32/libi386/bioscd.c | 17 +- sys/boot/pc32/libi386/biosdisk.c | 206 +- sys/boot/pc32/libi386/biosmem.c | 7 +- sys/boot/pc32/libi386/biospci.c | 4 +- sys/boot/pc32/libi386/biospnp.c | 53 +- sys/boot/pc32/libi386/biossmap.c | 108 + sys/boot/pc32/libi386/bootinfo.c | 216 +- .../pc32/libi386/{bootinfo.c => bootinfo32.c} | 316 +- sys/boot/pc32/libi386/bootinfo64.c | 208 ++ sys/boot/pc32/libi386/comconsole.c | 27 +- sys/boot/pc32/libi386/devicename.c | 4 +- .../libi386/elf32_freebsd.c} | 46 +- .../libi386/elf64_freebsd.c} | 80 +- sys/boot/pc32/libi386/gatea20.c | 6 +- sys/boot/pc32/libi386/i386_copy.c | 4 +- sys/boot/pc32/libi386/i386_module.c | 23 +- sys/boot/pc32/libi386/libi386.h | 14 +- sys/boot/pc32/libi386/nullconsole.c | 9 +- sys/boot/pc32/libi386/pread.c | 8 +- sys/boot/pc32/libi386/pxe.c | 20 +- sys/boot/pc32/libi386/pxe.h | 8 +- sys/boot/pc32/libi386/pxetramp.s | 10 +- sys/boot/pc32/libi386/time.c | 5 +- sys/boot/pc32/libi386/vidconsole.c | 458 +-- sys/boot/pc32/loader/Makefile | 48 +- sys/boot/pc32/loader/conf.c | 14 +- sys/boot/pc32/loader/help.i386 | 19 + sys/boot/pc32/loader/loader.rc | 21 + sys/boot/pc32/loader/main.c | 18 +- sys/boot/pc32/loader/version | 6 +- sys/boot/pc32/mbr/Makefile | 9 +- sys/boot/pc32/mbr/mbr.s | 4 +- sys/boot/pc32/pxeldr/Makefile | 35 +- sys/boot/pc32/pxeldr/pxeboot.8 | 21 +- sys/boot/pc32/pxeldr/pxeldr.S | 9 +- sys/boot/pc98/Makefile | 4 +- sys/boot/pc98/Makefile.inc | 6 +- sys/boot/pc98/boot0.5/Makefile | 4 +- sys/boot/pc98/boot0.5/boot.s | 4 +- sys/boot/pc98/boot0.5/boot0.5.s | 4 +- sys/boot/pc98/boot0.5/disk.s | 4 +- sys/boot/pc98/boot0.5/selector.s | 4 +- sys/boot/pc98/boot0.5/start.s | 8 +- sys/boot/pc98/boot0.5/support.s | 4 +- sys/boot/pc98/boot0.5/syscons.s | 4 +- sys/boot/pc98/boot0/Makefile | 4 +- sys/boot/pc98/boot0/boot0.s | 4 +- sys/boot/pc98/boot2/Makefile | 38 +- sys/boot/pc98/boot2/README.serial.98 | 4 +- sys/boot/pc98/boot2/asm.S | 4 +- sys/boot/pc98/boot2/asm.h | 30 +- sys/boot/pc98/boot2/bios.S | 4 +- sys/boot/pc98/boot2/boot.c | 11 +- sys/boot/pc98/boot2/boot.h | 14 +- sys/boot/pc98/boot2/boot2.S | 4 +- sys/boot/pc98/boot2/dinode.h | 131 + sys/boot/pc98/boot2/disk.c | 17 +- sys/boot/pc98/boot2/fs.h | 556 ++++ sys/boot/pc98/boot2/inode.h | 166 + sys/boot/pc98/boot2/io.c | 6 +- sys/boot/pc98/boot2/probe_keyboard.c | 4 +- sys/boot/pc98/boot2/quota.h | 206 ++ sys/boot/pc98/boot2/serial.S | 4 +- sys/boot/pc98/boot2/serial_16550.S | 14 +- sys/boot/pc98/boot2/serial_8251.S | 6 +- sys/boot/pc98/boot2/start.S | 6 +- sys/boot/pc98/boot2/sys.c | 5 +- sys/boot/pc98/boot2/table.c | 8 +- sys/boot/pc98/btx/Makefile | 2 +- sys/boot/pc98/btx/btx/Makefile | 18 +- sys/boot/pc98/btx/btx/btx.s | 117 +- sys/boot/pc98/btx/btxldr/Makefile | 9 +- sys/boot/pc98/btx/btxldr/btxldr.s | 4 +- sys/boot/pc98/btx/lib/Makefile | 11 +- sys/boot/pc98/btx/lib/btxcsu.s | 2 +- sys/boot/pc98/btx/lib/btxsys.s | 2 +- sys/boot/pc98/btx/lib/btxv86.h | 2 +- sys/boot/pc98/btx/lib/btxv86.s | 2 +- sys/boot/pc98/kgzldr/Makefile | 29 +- sys/boot/pc98/kgzldr/crt.s | 16 +- sys/boot/pc98/libpc98/Makefile | 31 +- sys/boot/pc98/libpc98/biosdisk.c | 258 +- sys/boot/pc98/libpc98/biosmem.c | 6 +- sys/boot/pc98/libpc98/comconsole.c | 25 +- sys/boot/pc98/libpc98/gatea20.c | 6 +- .../dev_net.h => pc98/libpc98/i386_module.c} | 12 +- sys/boot/pc98/libpc98/time.c | 4 +- sys/boot/pc98/libpc98/vidconsole.c | 530 +-- sys/boot/pc98/loader/Makefile | 46 +- sys/boot/{pc32 => pc98}/loader/conf.c | 12 +- .../help.i386 => pc98/loader/help.pc98} | 2 + sys/boot/pc98/loader/main.c | 9 +- sys/boot/powerpc/Makefile | 6 + sys/boot/powerpc/loader/Makefile | 116 + .../{alpha/common => powerpc/loader}/conf.c | 43 +- sys/boot/powerpc/loader/help.ofw | 2 + .../bootinfo.c => powerpc/loader/metadata.c} | 258 +- sys/boot/powerpc/loader/start.c | 107 + sys/boot/powerpc/loader/version | 7 + sys/boot/sparc64/Makefile | 6 + sys/boot/sparc64/boot1/Makefile | 31 + sys/boot/sparc64/boot1/_start.S | 11 + sys/boot/sparc64/boot1/boot1.c | 663 ++++ sys/boot/sparc64/loader/Makefile | 114 + sys/boot/sparc64/loader/help.sparc64 | 1 + sys/boot/sparc64/loader/locore.S | 114 + sys/boot/sparc64/loader/main.c | 514 +++ .../bootinfo.c => sparc64/loader/metadata.c} | 268 +- sys/boot/sparc64/loader/version | 7 + 449 files changed, 33235 insertions(+), 10864 deletions(-) delete mode 100644 sys/boot/alpha/boot1/sys.c delete mode 100644 sys/boot/alpha/cdboot/cdboot-4.0R.gz.uu create mode 100644 sys/boot/common/dinode.h create mode 100644 sys/boot/common/fs.h delete mode 100644 sys/boot/common/load_aout.c create mode 100644 sys/boot/common/load_elf32.c create mode 100644 sys/boot/common/load_elf64.c create mode 100644 sys/boot/common/ufsread.c create mode 100644 sys/boot/efi/Makefile create mode 100644 sys/boot/efi/Makefile.inc create mode 100644 sys/boot/efi/include/README create mode 100644 sys/boot/efi/include/efi.h create mode 100644 sys/boot/efi/include/efi_nii.h create mode 100644 sys/boot/efi/include/efiapi.h create mode 100644 sys/boot/efi/include/eficon.h create mode 100644 sys/boot/efi/include/efidebug.h create mode 100644 sys/boot/efi/include/efidef.h create mode 100644 sys/boot/efi/include/efidevp.h create mode 100644 sys/boot/efi/include/efierr.h create mode 100644 sys/boot/efi/include/efifpswa.h create mode 100644 sys/boot/efi/include/efifs.h copy sys/boot/{arc/lib/time.c => efi/include/efilib.h} (73%) create mode 100644 sys/boot/efi/include/efinet.h create mode 100644 sys/boot/efi/include/efipart.h create mode 100644 sys/boot/efi/include/efiprot.h create mode 100644 sys/boot/efi/include/efipxebc.h create mode 100644 sys/boot/efi/include/efiser.h create mode 100644 sys/boot/efi/include/efistdarg.h create mode 100644 sys/boot/efi/include/i386/efibind.h create mode 100644 sys/boot/efi/include/i386/pe.h create mode 100644 sys/boot/efi/include/ia64/efibind.h create mode 100644 sys/boot/efi/include/ia64/pe.h create mode 100644 sys/boot/efi/libefi/Makefile create mode 100644 sys/boot/efi/libefi/arch/ia64/ldscript.ia64 create mode 100644 sys/boot/efi/libefi/arch/ia64/start.S copy sys/boot/{pc32/libi386 => efi/libefi}/bootinfo.c (60%) copy sys/boot/{alpha/libalpha/alpha_copy.c => efi/libefi/copy.c} (65%) copy sys/boot/{arc/lib => efi/libefi}/delay.c (77%) create mode 100644 sys/boot/efi/libefi/devicename.c copy sys/boot/{common/devopen.c => efi/libefi/efi_console.c} (53%) copy sys/boot/{alpha/libalpha/libalpha.h => efi/libefi/efiboot.h} (55%) copy sys/boot/{pc32/libi386/i386_module.c => efi/libefi/efifpswa.c} (61%) create mode 100644 sys/boot/efi/libefi/efifs.c create mode 100644 sys/boot/efi/libefi/efinet.c copy sys/boot/{alpha/libalpha => efi/libefi}/elf_freebsd.c (51%) create mode 100644 sys/boot/efi/libefi/libefi.c copy sys/boot/{common/dev_net.h => efi/libefi/module.c} (81%) create mode 100644 sys/boot/efi/libefi/time.c create mode 100644 sys/boot/efi/loader/Makefile copy sys/boot/{arc => efi}/loader/conf.c (79%) create mode 100644 sys/boot/efi/loader/main.c create mode 100644 sys/boot/efi/loader/version create mode 100644 sys/boot/ficl/fileaccess.c create mode 100644 sys/boot/ficl/float.c copy sys/boot/ficl/{alpha => ia64}/sysdep.c (91%) copy sys/boot/ficl/{alpha => ia64}/sysdep.h (59%) create mode 100644 sys/boot/ficl/prefix.c create mode 100644 sys/boot/ficl/search.c create mode 100644 sys/boot/ficl/softwords/ficlclass.fr create mode 100644 sys/boot/ficl/softwords/fileaccess.fr create mode 100644 sys/boot/ficl/softwords/forml.fr create mode 100644 sys/boot/ficl/softwords/prefix.fr copy sys/boot/ficl/{alpha => sparc64}/sysdep.c (91%) copy sys/boot/ficl/{alpha => sparc64}/sysdep.h (62%) create mode 100644 sys/boot/ficl/tools.c create mode 100644 sys/boot/ficl/unix.c create mode 100644 sys/boot/forth/beastie.4th create mode 100644 sys/boot/forth/frames.4th create mode 100644 sys/boot/forth/fred.4th create mode 100644 sys/boot/forth/pnp.4th create mode 100644 sys/boot/forth/screen.4th create mode 100644 sys/boot/i386/btx/Makefile.inc create mode 100644 sys/boot/i386/libi386/amd64_tramp.S create mode 100644 sys/boot/i386/libi386/biosacpi.c create mode 100644 sys/boot/i386/libi386/biossmap.c copy sys/boot/{pc32/libi386/bootinfo.c => i386/libi386/bootinfo32.c} (51%) create mode 100644 sys/boot/i386/libi386/bootinfo64.c copy sys/boot/i386/libi386/{elf_freebsd.c => elf32_freebsd.c} (67%) copy sys/boot/i386/libi386/{elf_freebsd.c => elf64_freebsd.c} (52%) create mode 100644 sys/boot/i386/loader/loader.rc create mode 100644 sys/boot/ia64/Makefile create mode 100644 sys/boot/ia64/Makefile.inc create mode 100644 sys/boot/ia64/libski/Makefile create mode 100644 sys/boot/ia64/libski/acpi_stub.c copy sys/boot/{pc32/libi386 => ia64/libski}/bootinfo.c (61%) copy sys/boot/{alpha/libalpha/alpha_copy.c => ia64/libski/copy.c} (72%) copy sys/boot/{common/dev_net.h => ia64/libski/delay.c} (84%) create mode 100644 sys/boot/ia64/libski/devicename.c create mode 100644 sys/boot/ia64/libski/efi_stub.c copy sys/boot/{alpha/libalpha => ia64/libski}/elf_freebsd.c (57%) copy sys/boot/{common/dev_net.h => ia64/libski/exit.c} (81%) create mode 100644 sys/boot/ia64/libski/libski.h copy sys/boot/{arc/lib => ia64/libski}/module.c (80%) copy sys/boot/{alpha/libalpha/alpha_module.c => ia64/libski/pal_stub.S} (51%) create mode 100644 sys/boot/ia64/libski/sal_stub.c copy sys/boot/{common/devopen.c => ia64/libski/skiconsole.c} (60%) create mode 100644 sys/boot/ia64/libski/skifs.c copy sys/boot/{alpha/libalpha/alpha_module.c => ia64/libski/ssc.c} (59%) create mode 100644 sys/boot/ia64/libski/time.c create mode 100644 sys/boot/ia64/skiload/Makefile copy sys/boot/{arc/loader => ia64/skiload}/conf.c (81%) create mode 100644 sys/boot/ia64/skiload/ldscript.ia64 create mode 100644 sys/boot/ia64/skiload/main.c create mode 100644 sys/boot/ia64/skiload/skiload.cmd copy sys/boot/{pc98/boot2/probe_keyboard.c => ia64/skiload/start.S} (64%) create mode 100644 sys/boot/ia64/skiload/version create mode 100644 sys/boot/ofw/Makefile create mode 100644 sys/boot/ofw/common/Makefile.inc create mode 100644 sys/boot/ofw/common/main.c create mode 100644 sys/boot/ofw/libofw/Makefile create mode 100644 sys/boot/ofw/libofw/devicename.c copy sys/boot/{common/devopen.c => ofw/libofw/elf_freebsd.c} (52%) create mode 100644 sys/boot/ofw/libofw/libofw.h create mode 100644 sys/boot/ofw/libofw/ofw_console.c create mode 100644 sys/boot/ofw/libofw/ofw_copy.c create mode 100644 sys/boot/ofw/libofw/ofw_disk.c create mode 100644 sys/boot/ofw/libofw/ofw_memory.c copy sys/boot/{arc/lib/module.c => ofw/libofw/ofw_module.c} (83%) create mode 100644 sys/boot/ofw/libofw/ofw_net.c copy sys/boot/{common/dev_net.h => ofw/libofw/ofw_reboot.c} (73%) copy sys/boot/{alpha/libalpha/time.c => ofw/libofw/ofw_time.c} (65%) create mode 100644 sys/boot/ofw/libofw/openfirm.c create mode 100644 sys/boot/ofw/libofw/openfirm.h create mode 100644 sys/boot/pc32/btx/Makefile.inc create mode 100644 sys/boot/pc32/libi386/amd64_tramp.S create mode 100644 sys/boot/pc32/libi386/biosacpi.c create mode 100644 sys/boot/pc32/libi386/biossmap.c copy sys/boot/pc32/libi386/{bootinfo.c => bootinfo32.c} (51%) create mode 100644 sys/boot/pc32/libi386/bootinfo64.c rename sys/boot/{i386/libi386/aout_freebsd.c => pc32/libi386/elf32_freebsd.c} (62%) rename sys/boot/{i386/libi386/elf_freebsd.c => pc32/libi386/elf64_freebsd.c} (52%) create mode 100644 sys/boot/pc32/loader/loader.rc create mode 100644 sys/boot/pc98/boot2/dinode.h create mode 100644 sys/boot/pc98/boot2/fs.h create mode 100644 sys/boot/pc98/boot2/inode.h create mode 100644 sys/boot/pc98/boot2/quota.h copy sys/boot/{common/dev_net.h => pc98/libpc98/i386_module.c} (81%) copy sys/boot/{pc32 => pc98}/loader/conf.c (90%) copy sys/boot/{pc32/loader/help.i386 => pc98/loader/help.pc98} (94%) create mode 100644 sys/boot/powerpc/Makefile create mode 100644 sys/boot/powerpc/loader/Makefile copy sys/boot/{alpha/common => powerpc/loader}/conf.c (80%) create mode 100644 sys/boot/powerpc/loader/help.ofw copy sys/boot/{pc32/libi386/bootinfo.c => powerpc/loader/metadata.c} (51%) create mode 100644 sys/boot/powerpc/loader/start.c create mode 100644 sys/boot/powerpc/loader/version create mode 100644 sys/boot/sparc64/Makefile create mode 100644 sys/boot/sparc64/boot1/Makefile create mode 100644 sys/boot/sparc64/boot1/_start.S create mode 100644 sys/boot/sparc64/boot1/boot1.c create mode 100644 sys/boot/sparc64/loader/Makefile create mode 100644 sys/boot/sparc64/loader/help.sparc64 create mode 100644 sys/boot/sparc64/loader/locore.S create mode 100644 sys/boot/sparc64/loader/main.c copy sys/boot/{pc32/libi386/bootinfo.c => sparc64/loader/metadata.c} (50%) create mode 100644 sys/boot/sparc64/loader/version diff --git a/sys/boot/Makefile b/sys/boot/Makefile index 7c196ac910..f3f587e74f 100644 --- a/sys/boot/Makefile +++ b/sys/boot/Makefile @@ -1,15 +1,32 @@ -# $FreeBSD: src/sys/boot/Makefile,v 1.6.2.1 2002/07/17 14:23:14 ru Exp $ -# $DragonFly: src/sys/boot/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/Makefile,v 1.18 2003/08/16 02:48:20 obrien Exp $ +# $DragonFly: src/sys/boot/Makefile,v 1.3 2003/11/10 06:08:19 dillon Exp $ +.if ${MACHINE_ARCH} == "amd64" +.MAKEFLAGS: MACHINE_ARCH=i386 MACHINE=i386 REALLY_AMD64=true +.endif + +.if !defined(NOFORTH) && ${MACHINE_ARCH} != "powerpc" # Build the add-in FORTH interpreter SUBDIR+= ficl +.endif + +# Build OpenFirmware library +.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "sparc64" +SUBDIR+= ofw +.endif # Pick the machine-dependant subdir based on the target architecture. SUBDIR+= ${MACHINE} # Build ARC / AlphaBIOS executable on the Alpha -.if ${MACHINE_ARCH} == "alpha" -SUBDIR+= arc +# (this is a WIP (work in progress)) +#.if ${MACHINE_ARCH} == "alpha" +#SUBDIR+= arc +#.endif + +# Build EFI executable on ia64 +.if ${MACHINE_ARCH} == "ia64" +SUBDIR+= efi .endif .include diff --git a/sys/boot/README b/sys/boot/README index cb301f52c3..2ededf52e5 100644 --- a/sys/boot/README +++ b/sys/boot/README @@ -1,5 +1,5 @@ -$FreeBSD: src/sys/boot/README,v 1.2.2.1 2000/07/07 21:12:28 jhb Exp $ -$DragonFly: src/sys/boot/README,v 1.2 2003/06/17 04:28:16 dillon Exp $ +$FreeBSD: src/sys/boot/README,v 1.3 2000/05/01 20:26:17 peter Exp $ +$DragonFly: src/sys/boot/README,v 1.3 2003/11/10 06:08:19 dillon Exp $ README file, for the boot config file setup. This is meant to explain how to manage the loader configuration process. diff --git a/sys/boot/alpha/Makefile b/sys/boot/alpha/Makefile index 05c72ce568..d7b22a0ed7 100644 --- a/sys/boot/alpha/Makefile +++ b/sys/boot/alpha/Makefile @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/boot/alpha/Makefile,v 1.6 1999/11/03 20:19:30 dfr Exp $ -# $DragonFly: src/sys/boot/alpha/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $DragonFly: src/sys/boot/alpha/Attic/Makefile,v 1.3 2003/11/10 06:08:22 dillon Exp $ SUBDIR= libalpha SUBDIR+= boot1 loader cdboot netboot diff --git a/sys/boot/alpha/Makefile.inc b/sys/boot/alpha/Makefile.inc index 0f362f44ff..cab4148de0 100644 --- a/sys/boot/alpha/Makefile.inc +++ b/sys/boot/alpha/Makefile.inc @@ -1,5 +1,5 @@ -# $FreeBSD: src/sys/boot/alpha/Makefile.inc,v 1.5.6.1 2000/07/06 23:29:46 obrien Exp $ -# $DragonFly: src/sys/boot/alpha/Attic/Makefile.inc,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/alpha/Makefile.inc,v 1.8 2000/10/27 09:36:34 dfr Exp $ +# $DragonFly: src/sys/boot/alpha/Attic/Makefile.inc,v 1.3 2003/11/10 06:08:22 dillon Exp $ # Options used when building app-specific libalpha components PRIMARY_LOAD_ADDRESS= 0x20000000 # "Region 1 start" SECONDARY_LOAD_ADDRESS= 0x2000c000 # "Region 1 start" + 48k diff --git a/sys/boot/alpha/boot1/Makefile b/sys/boot/alpha/boot1/Makefile index f1054c8cbc..861e257d29 100644 --- a/sys/boot/alpha/boot1/Makefile +++ b/sys/boot/alpha/boot1/Makefile @@ -1,20 +1,21 @@ # $NetBSD: Makefile,v 1.15 1998/03/28 00:21:35 thorpej Exp $ -# $FreeBSD: src/sys/boot/alpha/boot1/Makefile,v 1.10.2.1 2001/03/04 05:12:40 obrien Exp $ -# $DragonFly: src/sys/boot/alpha/boot1/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/alpha/boot1/Makefile,v 1.16 2003/01/26 14:32:53 phk Exp $ +# $DragonFly: src/sys/boot/alpha/boot1/Attic/Makefile,v 1.3 2003/11/10 06:08:25 dillon Exp $ .include <../Makefile.inc> PROG = boot1 +LINKS = ${BINDIR}/${PROG} ${BINDIR}/boot .PATH: ${.CURDIR}/../libalpha -SRCS= start.S boot1.c sys.c -CFLAGS+= -mno-fp-regs +SRCS= start.S boot1.c +CFLAGS+= -ffreestanding -mno-fp-regs +CFLAGS+= -DSECONDARY_LOAD_ADDRESS=${SECONDARY_LOAD_ADDRESS} -DMINIMAL +CFLAGS+= -DBOOT1 CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR} CFLAGS+= -I${LIBSTANDDIR} CFLAGS+= -I${.CURDIR}/.. -CFLAGS+= -DSECONDARY_LOAD_ADDRESS=${SECONDARY_LOAD_ADDRESS} -DMINIMAL -CFLAGS+= -DBOOT1 NOMAN=1 STRIP= BINDIR?= /boot diff --git a/sys/boot/alpha/boot1/boot1.c b/sys/boot/alpha/boot1/boot1.c index 45aa784eba..e53c4cd7c3 100644 --- a/sys/boot/alpha/boot1/boot1.c +++ b/sys/boot/alpha/boot1/boot1.c @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/boot1/boot1.c,v 1.7.2.1 2000/10/28 01:03:33 gallatin Exp $ - * $DragonFly: src/sys/boot/alpha/boot1/Attic/boot1.c,v 1.3 2003/08/27 11:42:33 rob Exp $ * From $NetBSD: bootxx.c,v 1.4 1997/09/06 14:08:29 drochner Exp $ + * $FreeBSD$ + * $DragonFly: src/sys/boot/alpha/boot1/Attic/boot1.c,v 1.4 2003/11/10 06:08:25 dillon Exp $ */ /* @@ -33,17 +33,40 @@ #include #include +#include #include #include #define DEBUGxx +void puts(const char *s); +void puthex(u_long v); +static int dskread(void *, u_int64_t, size_t); + +#define printf(...) \ +while (0) + +#define memcpy(dst, src, len) \ +bcopy(src, dst, len) + +#include "ufsread.c" + extern end[]; int errno; char *heap = (char*) end; +void +bcopy(const void *src, void *dst, size_t len) +{ + const char *s; + char *d; + + for (d = dst, s = src; len; len--) + *d++ = *s++; +} + void putchar(int c) { @@ -71,20 +94,6 @@ puts(const char *s) putchar(*s++); } -void * -malloc(size_t size) -{ - char *p = heap; - size = (size + 7) & ~7; - heap += size; - return p; -} - -void -free(void * p) -{ -} - void panic(const char *message, ...) { @@ -125,6 +134,7 @@ puthex(u_long v) int digit; char hex[] = "0123456789abcdef"; + puts("0x"); if (!v) { puts("0"); return; @@ -139,11 +149,11 @@ puthex(u_long v) #endif -void -devread(char *buf, int block, size_t size) +int +dskread(void *buf, u_int64_t block, size_t size) { #ifdef DEBUG - puts("devread("); + puts("dskread("); puthex((u_long)buf); puts(","); puthex(block); @@ -152,7 +162,8 @@ devread(char *buf, int block, size_t size) puts(")\n"); #endif - prom_read(prom_fd, size, buf, block); + prom_read(prom_fd, size * DEV_BSIZE, buf, block); + return (0); } static inline void @@ -190,17 +201,22 @@ getfilename(char *filename, const char *defname) return; } +static struct dmadat __dmadat; + static inline void loadfile(char *name, char *addr) { int n; char *p; + ino_t ino; puts("Loading "); puts(name); puts("\n"); - if (openrd(name)) { + dmadat = &__dmadat; + + if (devopen() || (ino = lookup(name)) == 0) { puts("Can't open file "); puts(name); puts("\n"); @@ -209,10 +225,16 @@ loadfile(char *name, char *addr) p = addr; do { - n = readit(p, 1024); + n = fsread(ino, p, VBLKSIZE); + if (n < 0) { + puts("Can't read file "); + puts(name); + puts("\n"); + halt(); + } p += n; twiddle(); - } while (n > 0); + } while (n == VBLKSIZE); devclose(); } @@ -231,7 +253,7 @@ main() char *name = "/boot/loader"; char *p; char filename[512]; - void (*entry) (void); + void (*entry)(void); u_long start, freq; int i; diff --git a/sys/boot/alpha/boot1/sys.c b/sys/boot/alpha/boot1/sys.c deleted file mode 100644 index 4e5e98d574..0000000000 --- a/sys/boot/alpha/boot1/sys.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1992, 1991 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - * - * from: Mach, Revision 2.2 92/04/04 11:36:34 rpd - * fromL Id: sys.c,v 1.21 1997/06/09 05:10:56 bde Exp - * $FreeBSD: src/sys/boot/alpha/boot1/sys.c,v 1.4.2.2 2002/01/19 02:16:09 iedowse Exp $ - * $DragonFly: src/sys/boot/alpha/boot1/Attic/sys.c,v 1.3 2003/08/07 21:16:44 dillon Exp $ - */ - -#include -#include -#include - -#include -#include -#include - -#include - -#define COMPAT_UFS - -struct fs *fs; -struct inode inode; -int boff = 0; - -/* - * We use 4k `virtual' blocks for filesystem data, whatever the actual - * filesystem block size. FFS blocks are always a multiple of 4k. - */ -#define VBLKSIZE 4096 -#define VBLKMASK (VBLKSIZE - 1) -#define DBPERVBLK (VBLKSIZE / DEV_BSIZE) -#define IPERVBLK (VBLKSIZE / sizeof(struct dinode)) -#define INDIRPERVBLK (VBLKSIZE / sizeof(ufs_daddr_t)) -#define INO_TO_VBA(fs, x) (fsbtodb(fs, ino_to_fsba(fs, x)) + \ - (ino_to_fsbo(fs, x) / IPERVBLK) * DBPERVBLK) -#define INO_TO_VBO(fs, x) (ino_to_fsbo(fs, x) % IPERVBLK) -#define FS_TO_VBA(fs, fsb, off) (fsbtodb(fs, fsb) + \ - ((off) / VBLKSIZE) * DBPERVBLK) -#define FS_TO_VBO(fs, fsb, off) ((off) & VBLKMASK) - -static char fsbuf[SBSIZE], iobuf[VBLKSIZE]; -ufs_daddr_t mapbuf[VBLKSIZE / sizeof(ufs_daddr_t)]; -static int mapblock; - -int poff; - -#ifdef RAWBOOT -#define STARTBYTE 8192 /* Where on the media the kernel starts */ -#endif - -static int block_map(int file_block); -static int find(char *path); - -int -readit(char *buffer, int count) -{ - int logno, off, size; - int cnt2, fsblk, bnum2; - struct fs *fs_copy; - int n = 0; - - if (poff + count > inode.i_size) - count = inode.i_size - poff; - while (count > 0 && poff < inode.i_size) { - fs_copy = fs; - off = blkoff(fs_copy, poff); - logno = lblkno(fs_copy, poff); - fsblk = block_map(logno); - cnt2 = blksize(fs_copy, &inode, logno) - (off & ~VBLKMASK); - if (cnt2 > VBLKSIZE) - cnt2 = VBLKSIZE; - size = cnt2; - bnum2 = FS_TO_VBA(fs_copy, fsblk, off) + boff; - off = FS_TO_VBO(fs_copy, fsblk, off); - if ( (!off) && (size <= count)) { - devread(buffer, bnum2, cnt2); - } else { - size -= off; - if (size > count) - size = count; - devread(iobuf, bnum2, cnt2); - bcopy(iobuf+off, buffer, size); - } - buffer += size; - count -= size; - poff += size; - n += size; - } - return n; -} - -static int -find(char *path) -{ - char *rest, ch; - int block, blklen, fsboff, off, loc, ino = ROOTINO; - struct dirent *dp; - char list_only; - - list_only = (path[0] == '?' && path[1] == '\0'); - loop: - devread(iobuf, INO_TO_VBA(fs, ino) + boff, VBLKSIZE); - bcopy((void *)&((struct dinode *)iobuf)[INO_TO_VBO(fs, ino)], - (void *)&inode.i_din, - sizeof (struct dinode)); - if (!*path) - return 1; - while (*path == '/') - path++; - if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR)) - return 0; - for (rest = path; (ch = *rest) && ch != '/'; rest++) ; - *rest = 0; - loc = 0; - do { - if (loc >= inode.i_size) { - if (list_only) { - putchar('\n'); - return -1; - } else { - return 0; - } - } - if (!(off = (loc & VBLKMASK))) { - block = lblkno(fs, loc); - fsboff = blkoff(fs, loc); - blklen = blksize(fs, &inode, block) - fsboff; - if (blklen > VBLKSIZE) - blklen = VBLKSIZE; - devread(iobuf, FS_TO_VBA(fs, block_map(block), fsboff) + boff, - blklen); - } - dp = (struct dirent *)(iobuf + off); - loc += dp->d_reclen; - if (dp->d_fileno && list_only) { - puts(dp->d_name); - putchar(' '); - } - } while (!dp->d_fileno || strcmp(path, dp->d_name)); - ino = dp->d_fileno; - *(path = rest) = ch; - goto loop; -} - - -static int -block_map(int file_block) -{ - int bnum; - if (file_block < NDADDR) - return(inode.i_db[file_block]); - bnum = FS_TO_VBA(fs, inode.i_ib[0], sizeof(mapbuf[0]) * - ((file_block - NDADDR) % NINDIR(fs))) + boff; - if (bnum != mapblock) { - devread(mapbuf, bnum, VBLKSIZE); - mapblock = bnum; - } - return (mapbuf[(file_block - NDADDR) % INDIRPERVBLK]); -} - -#ifdef COMPAT_UFS - -#define max(a, b) ((a) > (b) ? (a) : (b)) - -/* - * Sanity checks for old file systems. - * - * XXX - goes away some day. - */ -static void -ffs_oldfscompat(fs) - struct fs *fs; -{ - int i; - - fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ - fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ - if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ - fs->fs_nrpos = 8; /* XXX */ - if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ - quad_t sizepb = fs->fs_bsize; /* XXX */ - /* XXX */ - fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ - for (i = 0; i < NIADDR; i++) { /* XXX */ - sizepb *= NINDIR(fs); /* XXX */ - fs->fs_maxfilesize += sizepb; /* XXX */ - } /* XXX */ - fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ - fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ - } /* XXX */ -} -#endif - -int -openrd(char *name) -{ - int ret; - char namecopy[128]; - - if (devopen()) - return 1; - - /* - * Load Filesystem info (mount the device). - */ - devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE); - -#ifdef COMPAT_UFS - ffs_oldfscompat(fs); -#endif - - /* - * Find the actual FILE on the mounted device. - * Make a copy of the name since find() is destructive. - */ - strcpy(namecopy, name); - ret = find(namecopy); - if (ret == 0) - return 1; - if (ret < 0) - return -1; - poff = 0; - return 0; -} - -void -bcopy(const void *src, void *dst, size_t len) -{ - const char *s; - char *d; - - for (d = dst, s = src; len; len--) - *d++ = *s++; -} diff --git a/sys/boot/alpha/cdboot/Makefile b/sys/boot/alpha/cdboot/Makefile index ab9613d293..5203f844d6 100644 --- a/sys/boot/alpha/cdboot/Makefile +++ b/sys/boot/alpha/cdboot/Makefile @@ -1,5 +1,5 @@ -# $FreeBSD: src/sys/boot/alpha/cdboot/Makefile,v 1.3.2.2 2001/08/01 20:52:58 mjacob Exp $ -# $DragonFly: src/sys/boot/alpha/cdboot/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/alpha/cdboot/Makefile,v 1.7 2002/05/10 09:26:28 obrien Exp $ +# $DragonFly: src/sys/boot/alpha/cdboot/Attic/Makefile,v 1.3 2003/11/10 06:08:26 dillon Exp $ BASE= cdboot PROG= ${BASE} @@ -7,6 +7,6 @@ NOMAN= NEWVERSWHAT= "SRM CD9660 boot" alpha LOAD_ADDRESS= ${PRIMARY_LOAD_ADDRESS} -CFLAGS+= -DLOADER_CDROM_SUPPORT +CFLAGS+= -ffreestanding -DLOADER_CDROM_SUPPORT -.include <${.CURDIR}/../common/Makefile.common> +.include <${.CURDIR}/../common/Makefile.common> diff --git a/sys/boot/alpha/cdboot/cdboot-4.0R.gz.uu b/sys/boot/alpha/cdboot/cdboot-4.0R.gz.uu deleted file mode 100644 index ba205fbc20..0000000000 --- a/sys/boot/alpha/cdboot/cdboot-4.0R.gz.uu +++ /dev/null @@ -1,1555 +0,0 @@ -$FreeBSD: src/sys/boot/alpha/cdboot/cdboot-4.0R.gz.uu,v 1.1.2.1 2000/11/27 02:16:39 obrien Exp $ -$DragonFly: src/sys/boot/alpha/cdboot/Attic/cdboot-4.0R.gz.uu,v 1.2 2003/06/17 04:28:16 dillon Exp $ - -begin 555 cdboot -M'XL("$LIUC@"`V-D8F]O="TT+C!2`,1]"WA4U;7P/I,SR>1%)C!`K$#.S`1- -M0M2)C36W!7+.9&(F`358T'@K9()406F;MJCTOP))0$5>QEY4VOJ8B9.`C[9C -MG1#:&@V/W^*KC6^NM3;8H+S$H`'1*O.OM?6NR9W^NV9TEII=[O[6%5N5RN_=G,+^<+X5 -M\O:U_FWKP3M6;)VEBK0OE1XG@W]2\Q7]U(&5_9293!ACKOR@?TO&S,=P3?`"W`?K0JC+F"*>X?&K@J^O5DTGPTC]Q;/OR>YQ-D?=@O!9T6]C, -MKMNX%&W'VOE!ODASW3FCIJD;>;\MZ%O&;HIQ?R[[U:\F+>,Y37"WF^U?.#B"^VBV-I87:_ -MA3E"6>S]IR.1"@7F,62#[ZG0WUS;KLIFUN!8OGK%UI>N$C!N!QBFLEV5D8BC -M1,MQ>%LFGN]-@SZKT!Z6EZ#\P34KMO[VIZ+\;-[FY,[E+2NV9LP1:>605@[E -M3:S",5;NKQZ\8T6GO_FASN8[5VP]A^K9#/6^K!-I#-)NY-[ -MG(501KE[1J>.RP;*ZX4\?^O\H.^N&;SOKCMF``TZPKTP'M#O8WWJ@A?7+J/\`8SF,Z5:BC:7PFW&:6[`5:*RCC;WG1)I$^JN# -MO$&B/RO-[[4T%V60I[KS'3G,>MX6P/]71'N3$![@_"?ZG06_+5`W#WC`[^;3 -M_$_J<2+\P4DQ^"&@R\]7BOQ]DV(X60F?9.LC9*B/Z\,*>6NA'9U6VR8A??=7 -MZ^E?K!+IRR'=`F//^/A\6CU6/E3]3?,X%?MGI_[-G10_+CH>C/YA^RXHTV=L -MGRWHRF,KNQ3V<%>&/%B=)1^O#MT]HX.Q],Y,QCX8A'F0J(]#YR(?/-2][6Z< -M2ZD3\[Y80?V'/#^O5_/4%I[?\E3H[A6`P[K+^X&>_%0NQ&%DAK?=_1"VT=YD -MMKKK;,R-91Z@,AMXF:QPV]WSH4Q1>ZY+<;>9R@A[QG*ZX_F[>_.8OF*#7AQ=+[A$\8$^"WG4_Y`NI`!V^[^ -M6S`2>41A[+)@HQEX-<@*"VL)P9B%D,\R-A7*-JJ?(<^.F\\%'3!7'3!7':[H -MW,;35]TWD![5#9SNYSZN4[]4IB#?#XF^V8-9@#?.:QU;$,R3W9!G?Y3!G*V^[)\WI;#N\_>=P^TVPGM=D*[G=!N)[3;R=B/8O0/<+I)GHGVIFS5 -MVUI,;2V%,N>R596+VVNWLZ)/:(?3G07A.GQ]CX -M"+J4VJTLXXIZMC)HE9M4+YL9S&6:]@537Q_'V$#+;6H-8Y=S^9HRJ%8YTU;# -M[]:2G:P5Y*+3XX'/1LD!WPL\T*?I0&/4OVFAL82WWMZHL*1DL(H(5E$HPZ5J -MBV&L`^EN[56@`Z`7^QB`FPE_V%_H.^3]H[(2^JRWMQK:$_2-^D$ECGD)MKN3 -M@?3"S"R6*6V19\G5CP;QV6,W*A*;)6],*$_F2Z? -MYC30MPYK"E.&MMR]`F!NRZURGY;+2C0-Y@CE>"!]FG:*QL0X3L^A;E+6 -MK$TF6F6L\:SPF43XY`S#9WX"/AEQ^$Q.P*<)QJY]O$_UX=S`IU2N>$Q,@S]U -MH`[HC#%G&-H))EO/L#9Q37?`VNQH'D5^-$U(SK\S8>UF`.^VVO94%H)LVU,M -M^J9.$/K2-J(+"VN%>5ZEZ&L5^IT8C]*@ -MO(>7D>7WJ]/E?U0COS+"LG#^%E^/YP'L(Y&*`:R#/(5HKCV7%5W!=3;Y2#7R -M=\;<[84@]^XBN=<\7N?+]N!"GQ-IQAA+' -MUV70#USCAX\?RKUTP]C=0F,G0UF=A^O\.Q_Z%[J[!_!_*&CLIYOW$\>P2,W% -M\<'U5*>`;K\`ZCE4H"?0OV6@GQ3H[U3HK^3.E0_#O'IX?V=1?]ML0H:GPO@G -MCNT_@,9,(&.,_3/*`<[_;?'Z17H"_I,-_"*&?Y&&\R0S#=9+8_M>T#&@?/O% -MMZJUW[S55XLZAH76RN"X'J<$-"\U*1XS]*F7="Q]+?6-$[IVK$V[=@#P7@N_ -M41XTP7PMA[';06W@?"/?8&Q-.\(Y1N.P=MSHNDRR?[S_X\ZLWP1FJ)H=<+>P -MV4%3F:H:]>I`UU3U&Y"'^A?JH4U`#S^[EO2?L3W.#)`17M"1F];-Z(3ZG3L@ -M_SCA_`;DUQOXHX5E=9;.4;6QME9M&^B*SUU#_`_*`1$,@:YL-[;30.UL@/QS -M(!]Y?8H!'O)?7">72L!W4$=DR@$KZ(&EI=A&"V^CD]KP`HPTP'7Q.M07#U7C -MV#Y`>)9`WM%(9'=B^Q74?M98H8/"'N-$4S/H[NN$[FY/D`*G0MCJ/]#](A_)A?ROGSU&ZV0+IZ=#G4ZMQ'U#C=Z?B -M.G<$L7\60[DF*"9&HGD*X%YS`T\;"@PG[E1 -M=PQ>TTX-IYV%-"=;H-Z8A/&UPAP@C_"UKMCJTOL/YFCN9&&H4O -MQ/7?&N,/7J"-0M"K`!]0I^T4"2RRAXP3]/& -MXO@1S@,_$NWY`%X&X)C)5%@+AZMS;<]'Y\1)T%>9H' -M9(5V]UR[!^D?>?ZI*K+_1.$5:UF05PY]=T&;K\J_KL(U]#SM,0Z.@3WONIZ. -ML8;U"3).&T.\XPK0#2XV+]'LI:I;6;>B,X^OP_[JL:S!_=_R!1Z$]33!>G`, -MMGFH>@?TZX;+B/^-01V7#>GX]1%^36/$VD2=`^4!ZKH6UGP`RY5"FU9J!^'_ -MBN!/1_AH2X&T6PE^(:3EL.83R&/'$3U9H9T)E&^!_$"7I/KG2:HD*YZ7RQ3/ -M`>`9QOFT`.V5LYGA7-N?*BWL>#?NQ?RG&UX?2;^I.XOUV98--)B$/I`N]G%] -M+*/33+SF>_]'X'I=-M+8RFZDG^H2LZ\@PS!?2RW=8A:,- -M8/ENH_FG.D6EBM:>?J@R,%[5=#WNTTC#D)/H3*]W%=7;EX7V`38P3\[/Z/UGX5]2`_K:WXL\/E^6'/?OIGV -M_SR_!O3Z65ROUT"GQSW#/MJKF\J8V\AK4#;C&(VE,2K/$GOW?6(/E$0'';Y> -MD\W/8&:/LVZ$]8MS=.IN,0=?_I#L/YG(K]@`TEE/(G^#M3IX]XQ.M&4@+\PG -M>MT`=3!/MP.E$W]:!NF9,#YFYOL<^=UC"?!P+=QOF%^I[/G*2$0K<>=HWM:) -MU=[`+1ZUI4SU;(2Q20?X,NC!1OF:#CS!!'_&<4P%GM,^OD"UE]I5:;#"$TAI -M5'?:5`_:#Q/+WL9M#44P-T4P-T73TT%'QGZT@7[72W02RA#TA753(%^O+P,> -M7)_F,)V0YM3G,=I^X`%%A;VDYP3086+;@1-3U6M0[YR+Z0607L#3'S7@+@,_ -M;4_1U%TVGV/P+^)2AG(1YQ3'6[=-?=WR-8XEC^",:PZ7I -M9".#L3U(]#,.U@S2T":RRWBA#*X_7`-S:(V5\;1#/&TVI2F0=HK;487<0-OE -M?*)=&?)0!J3KZQG*-',[Z)'J/."ECY(\?-?2XUP4R3^%NED_P'Z3^,\>"^JP -M1Y/:;T))]%G._Z".[PSVFS&DQV;*GX"L_+0ZMI[V5M9Q_(YQ_/Z+\)L.,$$_ -M.X5K\*=&_H?E`=\:W?X-Y?S7,/6C2#[,Y]XX>W/@E@+U0]B_6>=BN@O272(= -MYFX_I#/V43=C1^#O:#?JV:9E>RO=P_29P]4*\4WY5M&F/TW,)>A*\?1\7[&: -M0[8[U#%ET'7CUA;0D17J(%T<(EASTX3=4-=3A\&\I5@=PV%.0WO6J##?()@L -M3=@KLP"FE<,S]/V^0A7I%\OOI?)]J5@^.YS.[32'@%>I!Q+QZ.&T71+,X7O" -MS*CNO)7TE0T"1N?Z2#Y/#U#Z,DB_$V1PC-\EUX-U6X(_0=YR_2]U9/F:0315 -MOGYRIP)]>N(FLG^:Q;K!M$Y*.TAI2#^_UVC_8Q9Z5B[TV44P?DGE=YC%>L2T -M^R@M2&D(8QO!:(,T5L;4=*9HN3_*<\7>;-)A[4+`N99P&99UTO]MI3J8# -M7^?[%_';QOAK:!#(2S0[248^AVUD=!KEH07:PW*Y5&XH13'TLY_.L;.G\4_/N;I%M- -M@O+?8.Q@)`*\(*@R;4F]F03E,Z_OL@_<-(_H#%,'YF -M@3N,J?+!%C:EN58VQN5XVQO5BX#?3L7]"L+ZSV`<+$];"<5VDG4UW$^MD`^CM7M-%8* -MP.P`O-^)/'>`07HG]<=";:$\LQ,M#DD]S@G,?P+WL(/KD(:%S'V*]OQO2#&9 -MNXQP[H6TY9%'#N`<8?H/*7T;I/\D"7Y8YOM49HV$NF-SM&Z#+O^E1-O0<-X7 -M&FG_*R7G?P?7B;5U!?7%`N6:6F8$TVUV;K_44HO40(I=0]M>4\N*CL4MN!>I -MZ63LXLXTF%\+NPKV)>H'_01G.L'I9<`3;78-SPFTU&(.X_B(YSIGWA\UL>'X -M(Z\)S6#N:2!'<$UETQQZH*Q_M=CW3`:>C'LGI-E+*+^`\7,RSJ.LI"M8F9#' -M&2`;]ZT3-%Y$Y8TES&-U7;\(])P`FDJE]+#D)X79Q\3 -M;1^G=;@Y(MH&WL]IK(_;26JYG22/QK,I(NP_N,?::[!M]=,^IRXRG#84H_TW -M8CB_G8L]3CP&X0O[+]2NTMR:7-2B]UH)_P6^1VL_2I&AU::XQMICI=^ -M%=/C_Y-D4_U7R"M\)PI)1EY'9=6O1N85KB3ZD17*]YX>W3Z%8Q2)/&?/&F&< -M!H$_*"AOQU^!^N%0X+XK\%QD:%Z"_&)L?<<$PWBB+NB29CIT^]5/R8?B]B][ -MG-EHOY(6=*+N&C!K:*/DML00K!%<'W4Z_7\IUL=W.'V(N=A&<]%-Z[#D2S$7 -MJ&>]!;J^F`O-7YM:RWE=D637D`8DIGS$V$T=.@_&<4VE=@[^L\KN(Y*]JZGJ#T!R%]"&@"]U=,JG#X\/QJ -M,>D__T0[MN^`D'O/1WU=AHBN?/\<71:H4@+]_W/T\_$LLC^B/1AYZ1]N)/^/ -M+W!<5]D#Z4LU)_D;U:3^0$.<_3`'C.RYQVA?N?<+8<-`OO@_!"/\!;?Q=)[/ -MU-=1C\IBZ@DLL\50_SVJO]90_P6JOPS2\`P`<6A'NQ1S>-Y#60+U=E"9NB_$ -M_#?;U*J1QF2T\T7K%\/E"])\_5TKMN;0G!S]7.B!$NQK0/8-(1VVK8O9<7Y- -M?=CS.<[-X:2\>$3[W^3E_ND*]C/.G1^S<1@QXKJ4U -M\0GU*>]SG3]E,]4=+G<7I;3FG%XW# -MO8K@UAO@SB"X'L3;I9+?FYO[O;U%]%)"9913(Z^?YB3^0X.?C7:^!FOF+G%6 -MBWH2?(\[/W>GUFC\3(?M?UJ<[>ROSC/T=_-G`E^-E[,'/]7/^`UP)W"X*SK$ -M>,_2^+AQ>$7#X'D^HW'%<\A;%/5EN=@CX&,]+8B^=P%SB]9B4SU'H:W%M%][ -MA?BD_)G8>Q42_\&]T)]_0OSOI,BS0Q[60SD]D7C2RR<%O2#..KW@ODO01Q$_ -MZX8TKH?_\L>T_SG);31#R?"UWA6;OV.TQT79]RN2^]=!7?1[V&!3/#CF-:EW -M(QVB?YU?VFSWH'^A:#=2K1C&I^"D&!\?X&\!?)"_;R);@X7RL&_H^X?TIJZ/ -M^?YEZ?K?B61[Z9']DT(GDNO?.*=H,S'QL9D6_#)2,1")--B-]87OIB;ZU:9X -MT/;B8@NC_9D+L`/F#+0=#*!-0(R;\/<'AI^O&^=YG.%\ -M/1%?]-DL-^`;'.+ZW`#R:[2[)N+\\;!]PIGQJQM*MC\8K`[,TS3TVP`]PO$9 -M[`T3\49;6QR^5CN>[P\@ORPTX#SXJ3C?-^+)]S-)>'Q2_\=/D^.7B$]N%!\[ -M][M#/0;7RY_I+&#QI_R\!<;G4+5^WI)L_/!,]^O('^NG(_,WU`TRN6[P">BE -MXASH91A+"?0H!>1,_?K)'$_N_ZOO?S_I<=:13MI-:4]^(GQR=)Z6S7G:_`[8 -M'W*\O>NY;P2O\SC56?Z)&'>]S!`_^\M7BN+L]8DPT3?&N'ZN!"*.W=N9N]E6A+6`\X^_?QY/XYZ"^`_CE&7X!%Q\4>`63""87-!'R+P_`)8U<:%+;F6-ER -M*IM*9;&_%BAOU!<4LK=4D=XM<]P/59_I7#W._WW0X'_,K%';KHM@A@:'^PG' -M]1_R>\_"?S.':-'$^K]">'.A'[CW\ZY&ORHM?)#;Y7:66%A+20X+E*0-*I[G -M4W=Z*W-:O*MM_9X]J2W>JIR`]P[XGBKO]LCR'3#/C262S:'^B35ZD[?*:Y:!'&^/P5J8N]$IRH2=%OL$#9:=;6/MT*#_= -MBCZ'-K>J,:?W1ND?WC1Y/\!]?WH&WT_\W9[,IC*>VU1Z.A:W/)3@;U>$\P2R -M2?D`]T9\_=/9RN*/:2_,Y:76(6PL%P#,$@X3^;WP"?@8]+TCU>>B'DJT4`)U -MQW!:B-^/X3Z\G^R93#Y6?28_/37)_K'O&/`WVC_N@W78;!/[1F`NS!Y`LTE$^H&U:3 -M;'KY*/*:$@W/\U%_"Z3/TI!?I_,UT&#'WUE,5 -MOL_#^GK;&='[+J(^CDL>X5EW5.C06%>'\[0$VAZ5OPT>@3W\ -MZ3/SISIIRG;]+.,;F47=&7#;SR#P'4V%G@9GEN8::TM`AC/\W/GC[F= -M_E(:Y]F0[I6$7WPZS/]W6/,!84\L\H,..G@-4U]OYFNMB*^7>V^A\U^HI\+: -M]<+:Q7TLKMV%^OVG0\(?"?+;#T+_2%'6+__17"?.81]+4)_ -M6`_J=5Y:RS?36#UX2.";DS!_RP%>';23Q6JX;^B-!&_I(:2!!KLY\;R)%74\ -M'ZDX@?!UN7L5M5%^"'UOFN/.$[-A;*QL0X=5_HBOD6HJFP5E3T4>.9%HNT@F -M`WP)]J6^@\GW-SJ?_M8--/]0K@G2^F3F0=Y1KM/_0?(_@[9-93ZMW*"?##\C -M+^!V5]/I!7G,B -MP??""O`1]S3"_>B'0HY9R<],HGEY`](S`'X&M2=Q?*4+ZW*DV@S0Z]LFIM6B -M#]J;='X9_!#OM<7C#O,WI)"OVDM4[O8/Q5D4SM%[NO[_X6AGN"/[![L^'/G\ -M6[];P<__ZONNY#N0R;\7E>R$L;+/*5#MT`?LA^.DW1N8 -M.$N]6E(&!D>+C?NMUODF>H1'X5UJ5W'_GNB_9!]_ -MGJK?^XG202GHH)GGJ94F)\@Z@#,WOFT9X#C'WP#C;N!'QG+4'LI)YXF; -M5`G*.4_ALE$`6R`VC6.3T=ZMX;Q_\2?-Z@ -M[W=#>RESXWW4VL=?I`;&3^.^:2U,'3;']MS+>)\^DN:^/PY -MH2^%:J!;47^"8P)]7!@="S.G"_%[;-QX&,H:QI__/EX<]0M-.G['SXN. -M"]X7ES:?&6<\6TI!&,OT.1!XVZ%-^P/-WA16H<;E&_#'NU@CSN7GD -M^42\TR$_ZN^W#'T+D\WQZN@8[D,B#D]4WR1EQ/K=%;-M5C]*=9`7KK:/8[ -M_PG9'9HG0UVK9\3[7_T]SK:SL`]XV93M=6SF=JO\"=>1O=SFL?]IE9U^VL=. -M=W\.^E$=R+EOD\]M7K_0S3-!E_R$]1\X3\(S*FA7SG>@7ALB>3CX]QYG-I2K -M!QA_3)@/QTFM)G")ROFK#.LN,$]5%\#WIZA<"N@SQG6*\YO!^9-/2_!='L@$ -M/3R2(NX7=@&,"K2/\OKIH$^DUZ(N\33L'_$^C@_Z!OQIR.B_@_0JX=T$!KH_ -MU&O#W[R^4??QP'K2U/8'Q'I"&ZB/+0AF,Q5X08/]>.21`R;Y2&C_3_OPF]=`)33[`-DSLWPO[XVH3YSX!Z1G]?W"\EZG>C^?L* -M?5',SR:8'\:*H7_%^#D=<=H)8XYG+N/H/`;W8+\D^TC]WX3OH17F"^T].'87 -M2[-5]*%?TD#^OU"FZ*2]AH]K2HWZ`LQY%L.SDEK@2[7`EUZL$7RI>#J.Q1/C -M%36SW%>5*=^DX5I(G-]*P!GO![38FJL*D8Y'H)6?`MX*^L##N`5AW#)U?0%^ -M+X'?:8;?/X7?*8;?J^`WZMB%M']O>K?'68'W/&"=HC[\#5J7]>^BCBSV,>,I -MS?.NV"M/)7BGUL_H4-E,;G?#^^KXW0OTCG>S53:EO6X"79Q$^Z8W_AK#88CJ]_(T@>O'E/;D7\_L -MOX5[JZ8D]K6FOR;7WW%^3JU?T1%_'HOG?.G1^R)_H?9+_BKN0G`[R0JW=B+A -M_&(D?U!N_W@G\?QGL-HJ'\<]@#^PPL'7.^X?]I#/4"^4/\5MBC4P[K@'D,)X -M+PQ^AUC"_;YX?][D[3<9VL<]6?M"FO]W$N]=C;#_>>?LX@/H=K`.W9_\N);L?_N$[4>O6T-UPU3W!+1MA*U1_F;(;SZ9XI49 -M&YP$XX5CT7+2Z3V'*?T@WTXL!GYPJ6'\RUM%3`H+*^*V\30Z?YZ]C]MS!WP; -M)O,\Y!]YM$9=^Y`G5-A7`!Q<,Q<;X.GX3"9\9`.^609\QU/^P-N0?U+R-E^= -MXIT$^8GZ+V[>RBH)LF%,+\Y^HVR#LMQ\1 -M_#5O"UROBNYO&NS&^RE70MXLP^^U0%,39M/]C[>%O3:-J0>\&_!<[DBU;M<^ -MT$CGWV\+N\)%P&/+H5]_HE@O690NX?R6,177!;XHX!CKT$LG#Q:C$' -M6.9/^OG_6SC^6>%TX(61_`J0A_8JU(?P?KI=-YXV#MV$!?1?\A%\#/Y/1W%/"L<.":POQMP!-N(3KT -M<%SOX6?4.&YF&"_NQP5E'J18.@IOXQBW'YY/ZS'KK3/:B)/&*>#VKS=A+9\% -M?]'OL"!_R9`_!5XSQ'5/D+U!!ZQ_L>9KD)\.!>Z[%L_TAS#^`M+?+60K6_1F -M;*VJ,`:P;@9P+>KZ!U,J'-A?]*?K:X7U,9?X/]0KYVNCF-/;'/W^*^*.YXQ\ -MS(]4H^^I\0QQZ`V218&)P(;2;1^TJ.O][`WUL -M!:PZ&'EUC==U]'?WO1E_.@+PJUS\L#3%PV0'[F9I^&^HG]/@7F=F8H#_"2T7U)>OB34B1_-?Y/EZ_*AW7Q-WLJW$ -MOWKT^U^0;J&T'906@C1%^I%V1KOR"/?#FEX3ZPOJ=>?!^E)@?14"_BY87^6P -MOE187UY:7RB_Z]B"[4)^]W+Y/1`GOX]%Y7>(YL;Z6NR,QBB_W\(UI8B]X`6D -MVPR\&KV/>0)C'[TR[/Z'.'MEBIC_B_3Y?U7?,?M -MU?,0;9;*&YKT,YH6RHMK0KH6^ -MSQN1[D6Y//9X!_"'$Y:-@J:U)"OR^NA\$^^$ -M$_Q,@O_E7P3\F@3X:8#?*2Z[CD5EZQC:+^[]BU@SNFP=_![1/Z4;9>OG-*Z; -M_R)D*XZ[!//1VQ*3K8-4INDO0K8.4KN(YW[:[\S]"\;?P+W*S+#@"1\#[_^( -MWPVU@3P;#S3F(MF)NA_(7]KO'JTVZ3(4_:6!QH->VO_\!?<_N$=JY7(T_GY/ -M3)[N)?KJ^S/W0S^@GU?\3O=__[/8!Z&R_PNS88 -M&[3=^.%O&_SM@+\0_)E`_KX&^_`FX!)K[72V.][IWK7A'W2I;P^C.# -M-:EV;1\O)];FM52N[!644S7!0D@/I,SAML4^*%=J=KBQW)54+@O*[:7^U5+: -MJ9>%3Z?`<27@Z(3]P<*@&)/5:C:/)^/P%TLM&)>SB*&@W%ZLH'_T`2\>EEN-2#.-4 -M&PRD.-02]#<@WO\;\OL\^)*P`^)^'_4LC*&J[Z]??@GO_Q1#>[7!(K-#1=T& -M8V.!K%4SY87:.+QWJ_S=[F_]*FZ_#GRQICWE0C4#UO6+LN9!V$(O/@QK)!:O -M:RG`+S(7:VB7^212<4*W.;Q-N,V&_!#TP\*:J4\+./U:F9WC@;082&O!\Y0A -MO<\:]%GD+X!\30T!K>Y`G)EO(+Z,QF&8Y(5J(93'V&X[(*\]I57-`!X?WUZL -M[`ZV(!PKOR",MKSE4*^<%=!::-$J(A5#.V`NI2$%RLP,2\<5#W[B.IH.M%7. -MW/Y=5ZE>+)_!'+/'2.H!6-\P3\Y@IB1\-7&.JO3[7R_R>X5A66(#2`O87B$K -MZ-3IJ9+H:=*+@I[0;ZB7Z'Z#;O^!O*'H?DW<+\3Y0'G^';*KO?L"M&/.4"]" -MOR.J?[MN_X&\`:H?HKQ;*"\(>1NE&#_=1OD_H/PUD'^'(=]/^=^G_$4OX)W1 -MF4$<(^"3W2\FR*/C_7ZH(N^X#'@'8^=Q -M_H9^X0C3+,M:'OL^T.R=L.86\7AA"JOBM*.P\Z#-%K4]35-Q/Y#'#G0K\)>> -M*(]=_6H"'NK[0%,";Z1#)^P;'&@K'T!>8^)V]J/5A=T-=Q\G& -MFM:3E5[[2:T&;1%H-VYBZE`;C:V)QG;?GWJ<2+M>SN./@-[9?,C?^K<.O"<5 -M7=\!/..<(?WF,7N4_E?37;-)?T+ZS59OC.0/%?'R -M,X.X/\?RB!OR4L6`V]'G!>]$OGE#)'\@L5\<;UG@G3+D$Y_'?1[1C_6\'WA7 -M)=%_!?OXHGR!)PMH,!QYY'/D*W7LX?!RZO-6ZM=2:!_D>V?B?N4VBMTSF_(3 -M]RL_HOP2R&\BF#\GF'G/B_D+03]01]T&<^/CO*62RVP\3TG&L]"?QR@3N=R& -M=3&$L2*`QNHYG"F=YB@N+W%<9A,N_O^+.MOI;M!1@NM8,X]YEI5D/=GY_C4^ -M'J/>;@UOMXBWF\MI.[VSY7Y6FPE[1>2'$NF.9;RM*6&,5]8$[5GE-A7MV#B_ -M>>RFZ/QF03G15R,.+3S>4CW&FASOTS".#)YMH0_:&,(9??,4[IOG"$Y!_3WA -M?I#]@>8:249]Y_+^H_:Y_5J@;3]P$-0UFS57'>MV/IM\@_;MUN/6RQB -M0I21O;%WMZ!%'M,(9,PXR,?Y?YGB6?EWQ^YR?DC^IAMVB_''_ID);P?'2\2$ -M>Y//0\S'2[]?-W_F]^G/&'NS]PSV\\%=H%NZKC4FXKR;NBU[._2TD%HG;OZ']XOFX_;NXW^G?*.ZR5=`>:_:N -MV%VVP_RNK8B1V3C1#KJ5QL_"\7>1I*F!&0H?XRT;9P3E!'Z$]JUR:6:X7)KB -M^`/LFW2[?CJWY:*_^?Q@VT8]_D.%HD+9#4;\8/QOHIB".W;V.`$.OR=^'Z4% -M(6WM1G%WO(W2VB#M)X2':^.*CBPY4PVD+-5^@/)T8V)\V&G^A7Q_,,V_LP[6 -MZ$2'^@[PG0P;VIX.5S=O%+$GM$6T_@'VU=QF>KAZ.>5]F_+R(.]*R/LVZS^P -M%O@1XHITW*K;OWIU^A:^G[=3>C]/5S3K7(7'\_J`?.3V]L;60Q.T5X__&Q:A?`8B9A`_K-=63_A#KL -MM*+)>M5Q-K6-BE6\@NO^PY04/ZNO\KC?5USW&_U3.N[3KI -MS/>GK,\EC[^$=U!PO6*\!)S_+\DVTO\LC,=)$;HS=J=U'=H2F9Y&&*3YVDAB3J3S^ -M(/!@J-NW&O0S:K?\6:(ULO>%:1Z49X4-S\I\GQO]L9?2NF#/"G]L[T8]SI;P -MQPX3/OT]/R,]E[)01]CR"'>P1L-6-L7@X#Q/< -MM9`W*8$?%;*9_EUC%2\;%+8^M(^S7K=B!GT4QKF+0?N3#?1M8_D.;.\_]/5/ -M[94G]*6%VK3UQ&21A^:2]8C8@N@[8B;?"*3)=VG\^I_I<2;>,4/:\X]@OPT] -M,_+]@TPZ$^%W1X%7H-S.-MA'TN9\,:.8GR -MPF$8#Z319\EWO/`90:-&/U_]?H'-<+]`T+"=T]*/*+;LT3^"7EV*]]`U+97B -MO.TC>KN!RNS]8^P>PD?\'N.A,\:QY_>?_CCR_2?=1]??^E!'1AG&[TN(3U[F -MX_BBOY<>*R"/+8VNK;(_XEP5PUHIYFOE4X[7D:1XJ2.=__]A]/C"?9&&U]&N -MB6-]/8WU,W\0:RP=VD+_^7W -M*"/VP'>:\Q=B_!^1?!N-\"[D^`M -M_GV2>+E0IG>CN&^_@>JJAKJW4=T22`N<4#2,QXMY^ZC.*JJ39:AS$]4YM4/< -MOPQ\9>?Q^#%_!]7[,=5[8T>LWG54KW='K-^)_<5^VG,][L#;TU2L%T*9^\94 -M#\*\CF`V&V!6$\RE._`N0_]N(^YU5+[.4/X[5'ZZ`??W"/=M5,]-]?(,]2[0 -MYQ_2,FQNQ%E;0W$#IE#>P>[A_O=-9^%_'^H^\_W&,\5Y0!X0N$3E\C3$UCS`;3_)_J*8?P7Q'7YIEB\M"G#SLOP -M7+:HLQG:/DH\H!G:ME$YC#DMXHD[>*QO_?[@==N%;U[@$C?&XQ#QR3?%8DR_ -MH.]_MZ.?#>!:SCRCZ4KJ*/>W![OB_9_J6F+WC>%[@GZ>WEG.7)!?%,8SDE5T -M#_#)+A%;`.^G'=PHWDXYFWON_/RCZ]\;'Z2.XH-'QP?Y -MYM6D_T*>&`<-]$SU@#&^K0_FH9#5=C)V$\S'NDX7>YS/R2*:$W\X%K?C2H*W -M(2Q\`]`?M7Z3V!]Y*:^)YXDX7I64=AVV3^5F4IHWC/%YF@_DL>*.7![G$NFG -MIAW;\@).&-N?L24<%XUPL1EP*2$XC+=7U#$8J3A1SFH[7J287I,HO__I,\P/O:Z#VY<@><]01>KX?8Y?(,#[W^GX3+WC[]_N_OA,_G$JC#]7J#CUXW[;%*?B?.>K_)FN-T_A_1N636[X2> -M["+XNI[<36TH(=>DK`+DR`K=]?;C/`OIY@ -MW_Z4\/%`O?LT]6$QM7>1H3W!2[0.]"U!'>OOD?R#&;(J_%!P'JT-#J-_2`'` -M.!G)'U*9.-OZC'PILY[2=>,E77BVA.?/=83_8`C/G]/#>%\S#_XPAHS"BD(' -M-_+W3)#6PG:SIKG@$V1\%^JCZTWHKROP_S/AORUT1A_8Y/Z?H='CYQOM3V/( -MOPIC!!\&NLF,HQNQKW33N.>%\#Y]OO+CN'@28@^KG^%'ODOS_UL>JV8`SXQ2 -MXNQ3AZI%_')!U[I\>N:WZ( -M"T3#;T/]@QM%G``MM5*\]\?W%B6=8_&>K#'^SV^%WHUQ9`,G -MEF#<+AX[!^DQ3'X*RF\%/2J;XO>$7^K[/\@_+[K^CG&?`HQ3MX'N)O;_AOL8 -M!:W"/QKFWP&\QDV\IB2,>0K3GH+^=Z8#':C9YASMXDW!;])K9?W4*T6_<;I*LC9_3=JQN!OJR_&9E_2;T5#HF5 -MGG<*UL,&&N/^7PO=0^>_4XWOE>"Y0>\C=HEMX';F=%NEIML]D#Z<>OR#7W,; -MP9!U4RR>XU+J8_.O8W8+/+=I.MW`[P"TC_=I>%\U<,G":'Q^M`,(^7VT>AG) -MB?=17IWE?HGW_]?)_6;ZD4QSG+%CW5MOUW"[92_S+]:28+]!'NBSH -M;W1_A;?H5J4&]-@J^/V4\-FKU)`WHV__5-K#GGH"?2PNX#%6\MCE7?^;^`%Y -MS!HT\@LK8T&9^U$JXHS%7*I^$:D8&*D^P[CBY,>'=O&O6Y_O?Y\8W7\&=4@S -MT?(]B??U$NZRG"-\*LF6=[AZK.W-.%O>GL?QS`'?'"GF=S>1!BZB^.=[%I#^ -M]SC&=A0V:;19H!WX/O(E6@-Y?P/ZP#R40;\ENED*Z8L!-\LF<:<\0+K87-X> -MOUC;(*W1YE7P>?/42NHWUD,[ -MTTZRCPT]%F\#_R.EO_L8V<##P@8^E6AMSV,Q.^@V/./%]U/H3=-MCXGXQ@CG -M,8*S^3$Q7O@.;B2BP#@KT;<-=+LFVR3L3"\3'-]C.G\X7(WI.GROGDYCJNK^ -M?X_QN^M#Y6RF?^=8Q2NQ$D_`/$T=0_!Y_!_"7WZ,XC39WJH\A39L@#.!X!_< -M)L9Z.Y\?X7]R*=5[>=OH_M.]H^QOVK:-S']PK!;06"V&1K"`[W>V4KE#ZM_$N'=7%OLC4%[8-XVRI)Y"_E5*9Y'$1 -MSBY^>FCK\/LS4X&'YH&.GI7P/G(>[!^MH)]#7AAQ^COU<^E6Y$5B_\@,;T^] -M3?FSMW(=+9K^*J67;>5O3T737Z+T25MC)^[Z;MJ"_0'A// -MI/F[IN6@9^#WKV`04][@?Y_7[U(-#>?;K]'\JU4=TF2FOKX'J]PP)SD4F^";=WB/>W -MN?SK./O[!2YV(<:&!%WG='>RN%.VN%C>L7A3Z3RF_,<\WMS%^ON_08HW)^(S -M!NM@S!+C>F.\N3JQMQS*NP=UF8^K\0WA`+WQ%0Z*.$HZ?7O9F,YZ&`\[Q?#< -M'.3OP@WHZ>=2^NU!$?\W(^IG\!&//Y0KUVI8-I=5N`N!QAZ@V(VS@R(>))11 -MA0W^YR+F -M/Y!!>#0:SB=TO#\B//9`V2S`&].]:V!]4OJ3C^I\ZDBU]1[!CW3X;8]2C'L\ -M&P-=Q`OC=P[E+7M4/U.X7!N`_B2^+]+$K@CZ8,XS9$U-)S^NQ?`;W_P:A_?[ -M$^0W^OX&YMFYK]5B]L,@VN.YWX'9R>/:)MK>353^!/JVT%A^0;:3?>TTEG06 -MN(C&LK=]^%B:J3_!=M1[FS\RCL,$REO;KH_#X>@XO$W^2DO;\=V+V1KVUVYV -MJ-#GL#'VV[`[J+87*E&?PW@^/Z1SZ\)V\8X!WNGR@FRN8RMC_B_M8GZ\%`^O -MA?HR%,`U$-/?%G'_9[%77TYE^@+H8S>&Z_%]T-=U-.<[`LGCA":[\S!J_/O` -MR.O?>GZ^(P1C^!7%VO-`V5[X_1\4)[4,?I<+GW[^SI8%QKP)<%]"^;9`\IC_ -MZ--3OO:A#IU7Q,>GDSK]?&\&^U:@\9D$:Z^?8L]B3.M[8O%Z;]#C/_DI=B+D -M(PY>JM?F'_Y>`+Z?>0KXY+W?J'"DPOZK$,\G*1Z6#\KO:)T?E/@YL/W".3GV -MVGLGGE];.OX\]QRYU)T+?_C=M"S^G'@0]UJL5$58I03+!K`.;HJ]OSZ-WFS\ -M\A%!#QA;)(N/Q0R*R7FH^A30E%V/__.(D*-HY]A,=7LAK1]@]@']?DSEGH2T -M@S0/R6C"-YK]]Y'D^E$N\'O`B[^%5L_J.M`N4\]<81S;XT0/98^(M8CS4L^T -MKKW\_>*%VG2T`6ZKCE6A73\B@-[16R-$U!_ZEIB?'Q9WQ:`7SB67;@OJ7X_LK0.51^'\F^IVCOOOEA?/R@]0_MR'T7<@EH\\H7=3+);H`U2N!,JE`.[(XW9L$N_FGOH>X -M?;H=WX"'?#>^*0\TK^D^RF/ISE_Y0^+.D00P8!^.>Z2#V)XD*RI\ALXV?NW@ -M@TGN?P,<].5[@6+!IO,W=HK\]DL$;(O@$R6]3/*BGXV%VP;SU63Z9=N#9SX? -MRZ1XN8OOB8^7B;QX'^GHZ$NOR27T]K*&;P#QF,B!2Q7N'X!E7^%Q@(5L>A&^ -MXW[PL?%VC!-\0+(^4\7IE^4K5?IY=<)X8+UG$`;"[5:T?V(,AS9_U03RD^@R -MP/\=?%%X7YQ]9JFCIK(+?CPJ82_#,CN/Y*-3%L[?/ -M(OD#DC50E<;]9X7L>9#Z:V+J@8"Y1N/[?VM[50:52<2W+5GY.C\OGZQ_:ZB\ -M/G9?4$QAOUG5SN8,;=C^YYV9TZ'OV/Y-=K?"7L?WC?Y".:_ME[`W* -M^GMBY_J_I[4V]`OQ?H$N'QZEM?_N+W2;4CK7%VXA>'M^@7JHRGV$A7U#^`;- -MIS49_`7W&SM5=X_@8_KYPX9?B'>$4(Z8J.SR7PC[]'6&\4CJ#T1W!/$.8`Y3 -MA[P$6S]_`.=1^\O6<3>[CCY^@QMB>VOEUO$OFXLP=VWA;_/ -M^13FY0#-V-`^#KP(VWF5V@EOP?,UN^9'^:C[OVZ)[3W/IW';L`5]$?,5^S#_ -M!OYVD$.]9WYG$UOEV`=U'BYQPRS/@828\Y"UH*QG9MRGI^=<#\?Q18:X.O<_7$*Y//A!K?QVUO^6! -M6/L':+S7/)#\#?!1XY\_,)I_U:?5B(_"BF`O6_,[M>6AN/=7$$^\!^B%.=]# -MN#*`%[B$J4[NH\T&7#"FY72O;#?M^=^]'\>I`L:I)(2\83+-6R'(@/$D"PYR -MGGNH6CTM^(G^=D8AT6>(8+7=+_S)^'N#4.\=C(=(9;;J]H_[<:Y]!Q`^\DK@ -M&>$SQ]@F^^?](\L7E"L*F]6![U@%+E'=B%]&W'G0\6KC^;F+%>,]";1)O@Y)?*F -M;Q$]6NX3\:51C_1R>7WF=^C-907N7%L!Z""E)7M8J;>@M%FUL^:#H!.X\2Q+ -MCVV4I\>SP!A7AGA4>%_`7CJ;QUV3,.Y:KD=-8:M44YD_3G=_U-RHGL=\>'_6 -M;88ZV$X:M)/"WP"N!'B5(K[5B2K^WNT!E'$\+TG<3RBCQ_W,Y7>.F@\:VUO- -MXXG>J+:_^7T>(PM]_R5HT\;C=L7C%;CE?&Y'15K$6*YF@).(.Y8Q2CWPA -MP&EF4\+^+F0#VY).;$8[=BG[`K>$9XI*4,3<*^,;XN"7#6#[ER(\:UI -MS_P@U+L$8XRR6AB36IBW"K44ZO#OH`O@>.6X^K6W$^)=FVQU/-[43MCK2\Q= -MDE)6I^UBE5['1$W$UX/V\P'.@^SPA4%VN.1)EG%!F+UXX1_9BR72YN]J\J#B -M>3MU?VU5SG[O';9FSY]2]WLKBVRJFB`_?]DS@',/*RY)V7R-MLM4Z=4RQ1TQE9W>[F6GPW5L -M2E<]>V^[#V,YW%_A==RJ\GP?6Q`"VACVAO$O#/S%S5:62'/W5NYFC=Y*-K,$ -MWY3%OMHGVF&M-'H\F+993W/PM"I,"^MI3IZF85J92,MA3K66PWV!PYW%X;X0 -M!W:.F9MA@MC96/ -M:E?95/?9T-.:-D%/OV$Q>GH<[_2XFK5FX'$8!VXGF\;?^K;?UE*3`;IS5IR^ -M*.[/_@_('`NW78KRZ)^O?\?[((&4*[0^/&\V7Z%MXFOSI0LM[*42*SM2DL3[U):\[YXBW%;[_*?6(5\O)K&F![WM3 -M,VNJO)Y)LA[+DN5=WGP#0"+;*Y2V,TE=FC79%ND[38M!%IQ`"TT`JV\ -M![3R'M#*Z7`]T,M(M)+X7G8V?Y_:GQ#C3N'\#&E)/Q<6[U/'T]HKL#X2TZZG -MV,/()Y:1#LWNZ7$NQSMC_)Z8T/GNH[.[@4V8MR#8),[XP]=R.GN)TTC+I8I7 -MY11?S<+>[_YWT3/*!"--XUW#Y=P'H3'T[Z)M;`-QSV,+P\UD!UQ%8W)T -MH]#+Q@^+9UIA3TF(C[`\X3[6#PG&MHV<_W*X2RAM\\:SBSO4-HK^6;:'/SNY\(9O.V;V6E=L5=@5_O^A:T,LL[*:@ -M"6CS:N8[B+%X`NF-ZG=Q/YH6B=N/1M(<]A;5T8K+$I()/&$`^IT)"'V.2CU:KE68>1 -MAZ@;!`^Y%'B(:M%EDC*`>OW%B?.'$3UL6N2JO-XL8XAV-AG-$VDZ?O_];W.%7+@F"VW*XA//2)P3=7 -ML/XTGD7U7'Y]\5K(?Q\%E$W'T+TPAG.\=9)KWH -M*\/ZJ+<(F1!)TY1=%KNG]3;-.X8UJ/66E1@GPK\8QCH;]48N5S"&C#*`M/`* -MG?5J_^P6?(?T=:!TVWO_`NAG< -M/ZL8Y$ZQ5^8R:V=--L@LW<]"LGG0#ZKD_S(-]!X_Q;OVQ.L(H`^9V'/*'66* -M)VMS0,WZ<7-5(.T>[5=HIYV+-IE%);O9(M"'"H#WJ9J1]YDP;;.>YB`^!VEA -M/4WP/L:6A$RPEF3<7X$<S(RJ_$[ -M;FWP6B!/`CD&\$(\[>0":.M1KJ-AFHGW6\#$_N4FZ3>>4:V]!\]W%I:`KEYB -ME)\6PE.7EQ96$RK$^-X)<,\=83QQC]I\ST,`VU."X[;+Y`'8!1P6CMERR-O- -M"KR)[6#?KI_C@[%9"&TN"64.[W^[M+N[W1.Z"]?,2E@S3E@S#X,^MDD5^EC*&=?-T)UBW=3@'0"@;0L+ -M=,ELEE]B[VL8@PIQ%7,Z+50'^$@\=M7[W5#GC'<3F\Z2/S7=&2_?T+Z+^M]5 -MH.,E^D^_`FE&&3?E#/&G%587Q'T_?S]^ANI&^V\J4S_(U>]3S%/=&7CG/7H? -MP;%]3-Q[Q0[@\78W?'+_1IP/N[E4Q=\ROY^1K\2]+\],02,^"FN",2WE-%8@ -M-2@F&$L+FQ/"NQ7(GY@*V]D_Y0VJ(_C8#:,@[XN]/D:U?XW2GW> -M_S/D6\^0/]@Z4K[`OZ\U1C^YW%]1^:"A[+BX^3_>#339[8*_Z"I/X^7+A73#^=$=A<>MP'9;WOW7X^91,=RC0?\$+ -MGV8#+@GW+7A;&"\9YWL;S/>Z:O)_:<$X:.G<]NDU^-#WMZ"_TJ&SOK\3:DE^ -M_H>^M1G`:Z0R-\Q#W5XQ%D/[5L\(>GE:.N?]A:S!H1KZ)O.^I8>G,38@ -MQF9_-W[FL?V@[ZB?%TN'*\OQ7@GWG7*$[+F:QL^N/E/H[.H0/Y]"G,X5_L+! -M24Q[2L"P^_>N%F^M79Q66XME7X5Y1_FS!=;3DS3/S!_IJ#<@_TS%]$XN5%XOR9D/Y7C?9^ -MSO'J6R5!:\LDU,V+@C^!S_;[?'@VJ&1"&^MMJB>#^_4+>D/YQ=_*Z=;4&Z'L -MWGOBW\HQL?=OCLF+(O]%$K[1=:2ZG"T)6NB,U<+?SRH*XMFJE=MJ:X*ZW@-R -M/B0-VCT4);.`*FD]O46^X'^6*U\[/(2:S2CWYL -M@30']T,5]9RA'5#O/,EXWTC0@MCO%_EEPG5D/+'_6LGSH.]B&MZ3*V>/`0YW -M^`LFMGAE^4[5>;+%J\G7JXUFI]J8AG]VU?&9'66?JLG`BB84>!U2BXKXM7X+ -M9!W3Q/?[5:^]&_Y@GU8`^04`)XTU#PCP*8;C+T[V7V]>8"]6LK<^KQS\,(+\4`;T<4WMVCP%N"=R_%.RV@PUN9A^\K -MK:P@G%+F`[A+.%S9`+?]:\.UCPC7;("[@?M@GAW,D>!AC"0?E$TEN'C&V4GS -M8J31;3!?+DX?1=#>_J,@QP)_P;Z273`#>%VP#P#)_>Q_@:;22' -MS_D5T%!E,`#K/-/`F_Q1>A$T"SIXZ-'3D01Y7Q/4YPW/7!+M,5\EZ.NGD\2Y -M,/I]HWSH^]G(YZ^ZC,CB[R<_@O$TN*Q(X78+Y#5[^$<7'[N;C@O'JD&^WI`(=`0\7[P@U -MJ/:T%F]Q*<;A7<=E-=K"8^M(Q)KTZ+ZV=QA^MFL((^OUL7?XQK2>0/6P?5L82_!/FD:WP_^$^I[$NUK -M[(F@*-L",JZ%OS.&[Z2UV'H]^1@#ZI[)'3*+*+'WE18#G565[&)57IT.T:\" -M]2_9U3SL_2C]3`_Y@\N'!_C/,E) -MZ/E,]&N]+:8?X3T!O!]LXG>%[5R/Q'E)B_)G%Z>;-J`71O32=^O(^R\^_[>. -MK/^:0/]=S'6"BU$W\-OO580OU*4*CU5;QS(ZK5S_%K'JL#T?;Z^(KYU4OL], -MY['6&.B0/YTCRDSG90X]70)_NDYHK`/]%T+\WVHWT?&?88.6[X5[QFE -M0YF,\-GXQ_'U?\OHZS^+;.:ZSMUDT+FQS;9;A-PJ8>H!+(-Q'?WF^#)+;\$U -MF1&>#/JP#F*^.]!>]E9H3'0!G[R<8:]//SLF+HR[HNQ@X_K>]IL;^_ -MXOHTQIB-IQ>QWRF.[G<0[N`RL0_",3:F[UMVYG?.^?QC?1@?!=]O@?%QP?B4 -MP_BH,#Y>]FQ7'7NOJY[>7\&Q:F,+MC-VM,/"2OP8/]G%7NHH84\$ZH'6_6P! -MS.&T8""%VY=A+*;Y4=^S`W]#ONV%WQCWTRXY>3Q']"WCNO:EFCJ4H@R<2M"U -MQ[#WX_@7QE9=RQ? -MLV+K[R\7,=UCXXQ^M_C+2X'@ZI7^W -MCB_J;F\!?OIOU&E?,_Q.ISX,V/Y;YHO/T=7"!==-9 -MFQ*_GK?!>/TG^@3"FL%U$3`W\OB[=>SFH`KK*6!>R/U7<%T%4BKY^8-Q327N -MM\7ZBL5+W88Q4`'?9+A86E=LO72>H,$GFWJ<;6Q*.'$-GUU[L?4L^K$`[[?` -M.,3W(\O0#W,"7%TN)L+#NY=CN6^5/O]X/C5[E#%?"?V\.:Z?'YEB\X]T:6&S -M`O@N(,XE\&$OQC"6V"IU'=IQ(7U;DO0B2/?SF*$?\W=OVEI6;/71V#7]"-^G -M.,1CGMNE8AY3'L?`)->HV%^$YY1N@OZL#%MXGXM5I$&4H\^=KAA&?P=/Q]/; -M#TUGR>^Z`WP]12KPG&%G%?I>8#O8)VFPTA/H=G*>W+)=]4J#3OY[HF&M]0]; -M:U^/!^%:^WE"O/U2WK;SLGNW*[6Y\&F22AUU>,=$+E5E+F>71N55X0_1;SXS -M/#:.#WZ]]8Y\\,>&^=[TULZ:"UX-:%G\/%#T$^:?VTY:K]:\IC85Z'(:MZ]@ -M7/FI,#[[[GDHF&6(9SC%=);\C.1-%KO9C_2CR056J^U>J4T!7;21[Q$>36E4#T56#2&.7#>^QL'7U3Y^-H;QN_Y1 -M#?N*A+9N#FH\]N[^IW&?F@5R#_U4L,_MU[C53R(-0VG;!KI';,Z683YKT&"==>&^WF2@ -MI__M'.*:941'.&_FV+P%<`^5`K3;LEWA-&R2[$H6S2?ZG+0#;PF"7%^\YF]! -M<1Z!=0(U_!U0F-_S6%\)!&!CO#O'0Y//XF.-:PW%7<(Y3,<:& -MYG_1I7IE)OD#GTG\/5%==\@B?0?GR"U70EE3"/?6D!ZZ&>_CS#,!S\7S(F7( -M\:JDRC!OF):)Y\O+@#^P=:H#\,#V\!VZL=#7%-FCQ?HS,_AS2>']0;ZZA>M8 -MR?LCX#1R.,>!)G0<[=R^%^N;F4U5-Z7N@;P@X+_>C_-@8D$UV5Q$YR&M4N7O -MK8XWJ>WCFU7TY9S$>?YP&G+=A'>$2*<:QH.^'K]''O1C@_T3V\<]B!W]7@WK -M$-\/XC)G6/R_@6K<1_([PB#+W%P7-87LI7Z06>(>R$F^QM>?-3TN@+%5V)%N -M[.-B-C.$NME2^,3ZR!^MP!K0>62N2W%+MKY*?#-&[#-G@F[X,.Q;\MUX -MKQ;ZT#G.]DJE;?,KE>-MKU;VP5[OH5HQE@.+Q7I--LY[(0_7P028EZ\B%8JX -MTZ+Q]Y2'K]FOQ_O'`@\8!^.^&'1=Z%O[6EC#S09=UTS\Q`,X_*O\_?.X\]I, -MLE,:S3Z+X/[R.,ZSL)^H_0)X"'0C[N;_](.OUU -M-^+^]LQ[I*^K7W%=@?M#'GDZ]&5D=QKU?23][KFK!#XOWS!JZ;<;XX -M]*_PZ\W1\^Y_;2[P[*DESI__?Z^+_`C@_"M]:HBK__5IZLJX^E\/?ZQ?\2_B -M?]&_B'_^OXA_SK^`_VF8/Z3?'*+?K$48_V[!UD(VL\/%%G24LY4=*GNXP\N> -MQ;A1'?7L=$TG:H)=9RY:/2ONJL,XTTE] -M&M#^:?7[@8^-Y./`[3\+>YP%M[+:WJM8;0I33J+=?16MY_]BZ@>L#>_?EL/QBT_+M3GNKGL"U\*^)O[^$.Q9S%7X%MD`Z(-#,OD(Q-XW*BAQ7-*LHH\=?)\. -M[86-^4=`=WK?8'\91L>)_AS\3I'!]]YJ@3AW4::(ZKNDG@7:-_3-1S$;N+P)U37P.1^Z/&'\7X.F" -M\:^C\:^#\:_SZNWC?7(=_]*)Y_/X$R)>&HN_^P7T@?X%C*?'XGOQ]]<3?/&2 -M_VL#?-J\]E(OOR-G[\;X70[H3P7L&^9`WAR.4V*^!/EX9RZ'^882Z^,:+;T$ -MUCK++>EEN9!GB>9A'#)%4J-Z(H[#3A@'[/.[!ISU\2H:1G__?_"U),$7]QU( -M=^\@W8TPUOS\Z[IX^9C'*NQY;2+.7%JED(E'OR?>/^6Q/FV[*E&N6U:OV%I- -M.OW+W\,]9K[J:IL?M%^";\W@^7(%[GV^U/UCRD'.83YC;C_::'29.EH<,<2O -M"6!C/;R7R>$:QA_SZ[Z7_'P59;R%J0=&B^>70C[ZET?C\V-^^H5U.>FU;1/3 -M:EGSBJV=UY+_PW_B/=TBJ%O$ZV:`WH"Q@0Z#+"GG,ESS.RY!OP4MA.?.`Y&* -M+PO;1-P4O,L;IK,Y_W^*&'/E;2LZK'>NV/HM@K\6T@/C96Z?#TQ&>8JQAR3Q -M'G:7Q.V[>8GOAUV2@?;LH<`E8]!N-60=_AZL(AOU?8Z/W8]["'S?54YRG^>= -M2,4!!N!1SG*1K*3XF-?+8:=_Y][?#W!_!<4/<_W40TMO9: -M\E^!.3@G]@XQCR5<172V",I8VB:3_TL_CQNZ@'#S7HOZ(;Z5'A_/=G+<[TCU -M.7'R,3%>A(A9<"6]7QUQ$_W70[_-Z>H1X`''(OD#)KFWTF3SJ/%QE_94SH\T -MO([Y$H^3)/QD_TS]VU8__*[3F>+G<_JO/YOW0XX(_(&>VNM%>^50SSJ8XS%! -MF<`\DYO'O)EO2J_^!K=_ -M5X\>/R:=WUO[I+JX5''SM_;*GJ\<%[V_7P+\K$3HL&KA[VCY((\46[_T_B6`/+S0'HMMR_7MV',YEG\'3_01<.)=0-=4Y%?`^SY -MP;HV$<<=^WA_`GW7M^&YPJ*@::XOKC[:S27NXU403H3+VR=\A%^<%A)M%/`V -M5ACCK]_U4!!Q!1R']0_*AQ#WP+SSR>Z&O*B@'6/33JXA_X^Y/$?L+C%> -MV+Z)Q]7)5ZZ'=D8:._1-JE_#XU?ZA5^K(Z2V"A@>O(.4$%/]DL$6\&3%2^\B#+HGBUPCY\>.+^Q,!HS%<:+R/EX`SZBR! -M;`WESX!Q+I/AC_SOVTS$_HB.?VN4S@:P;ZJ0H>U<_E])\O^J'F<%U$/[S6#+ -M_*"86XP]-XV_YXCM&=L>-JY\;B3_:'&WC.O#=55R^X=_M8AKG1)W/Z&H(XV_ -M'2'L+QA;Z(=>TG_F]#@_2Q*[^DSZ6VC.F>-;Z7Y"8V"M8LR6;'R;G.(PC0'> -M@F]UNIGO0ZFMN4KEM'N8;,;'HKY+WCD80R?1?T[<[?Z*[/<%[H2W`[7'`ZW!W(?SQ]Z=HK/!NIAP7[_Q0=2&;UL'?MV89 -MG7H\<#N-6;B.QP,_Y6)%_`W>0J9UQ<7/9Y?#&!1WN?A[%<5A%ZOI`CYRP@P\ -M4K2I=^!Z#%M)Y!NY(6VI+IF'M<*X]9C__*I?R5U_`V1<**^ -M9V4O=DFN9HP#'CK#VP1)XUMQ^]^5,?^Y[\.(^@;$@QESVM4T.IB2\9VGT -ME.ZA]WL@YCBF&L>!AK$_?[.ER-L6%L\+<$\I+!_SKV06N2]G'L^F@. -M!Z_0:>9P]0R*Y?UJMZ,QT0[S.^F/ -M$RUNN6*X/IA,?VZZ(MGZC51G$%S@SR=,K,&.<7OPK0LS]^T[%%T7+L+?Q&,Z -M'ZK.8NKKB?&<1_/O&[Q\^/TB%[\7H`[@.RMXEZV0?@LZ=H3]JT4LXX"YB,N/ -M0N[CZ/A_Q%U]<%O5E;]/>D]2G`\KB1P,Y.,]24EL1PF28Y.TF/@]Z45^=@(X -M!';26<`?2:AATED':)O=)6`G`<+N+,20H3L[6Y",XK!,_U`;Q3#;`>P`V^P, -MVZ&[=+>SPTP<<-@"+2MW'),I`]ISSKM/>I+\D9"VFYDW5MZ['^>>^W7.O;]S -M3L;R%W8?Y\'Q6U!^JT7\ZIB7?^OFWP[<4O`/=3=_M^>6W3R]_S2>[^78O=9G!>DX#6B935J;U\(\LHXHQA3U@:Q4!?J&9:M*\W\[VJG1WH#8;G4Y8:\0 -MYVS&J<8X)3);F;K&-E]D:DMMRO(?3G.KI-SLMN)R7>0S:&5*EE1-+(NG7JX3 -MAF?1<6C^;S//]9%_71++GYGBGD@QO,),37[)U$O<#U^9_K]M[O@H5JR["S!G -MK)BVECUG->^;;T%;NJ2?:U9?5@`-`L7-K4M[:%\P]P/<(U2*T_J)R3/?V5@: -MXUO_F,BZ5!/*!=`?B*9OK$/I]2:D\ -M'K/'UJ_5G,Y/0-]/_M*O_9U8JZ.?F5>A[1KE4U+HWWH>R/56.UR\'=CV&EM9 -M[[2B/S298E[\"N-OTE8X76O];IY?O2>8=K -M(N[5)?-OTC[_UL\P_SQTME*;LF);>NWCW[!\'=82#SS$@T):.Q_>,JS8JK7< -M!\K'Q(^+',N6,DQ<-O3_!9,GVH_M]KU.V/?M.'8S3=<,?)O]["`O_QE7;]^\ -MD/ACVAZ';>U]KZ6P-C#">Q;S%\M;;[.;+<7)T_R',GI`3IAI_^F%[T4MLB4UM9^^.!)+Y=]PBVE^/R2_=^6WPMK!.XW -MHWSOGXS/C.W'?R.7$1?/[$+N$KD*N^.J7# -M8\"S'9YV>.Z`9Q<\=\'3"<\>>'K@V0=/+SP/P7,`GH?AN0;6MF7L4$V_?86Q -M#T]AG_Z-8)=7G0F!Y6"!VH+V^9/N\)CJGSIO)#\W\>B:>(\J^&IH[8;U>KR: -MY:`>P<`TB/?L$W?IE>R<_V&>_T:@19D:;<.YH@/-HN\HT#S>8N6?Q\Y%S?RC -M;6B+V0=K%-"`>IJLN-<:5=2.\^8]F--/MB+V_M7$1_+T-`K)Z$*6^`1I%L33 -M4C??1+I*.:;F:>P*2&(YT'_QON`U=0?TO&$:N\3/&^B/L4ZA.?E -M"/1+@?^?)[`,S(?GPTA_3-P#9<42)D[Q!O@]^A.SOV-I(5PH-^F,J+B>,V&+ -MK(GH;[PK:=:!8^A_6W*YYD"-,!;#&.37P_OEZ.]_X;R84RCL)YJX,F;R4QCT -M1UC4RSH(RY7C>">T%9K$V,S"(WZ45P21:;@OF7JU$.LE'[F-_]1)L(OX4PBV)=5`^,I;50C]+8IP9A -M3=@*=$F^EV@L8#DNQ/7!>%B)YRK0W^X\#_PJZO:0QG"(>(;9H2+_L5SH#\*` -M6N6C+]F@<%@MSK^&?#U/GW]OPL(U3^0ZQA6@>SGUD#AG'\7=@ -M;+M\OXC%7&MBC&VGOC.$YU-_[D*Y7'.)=\'=[>A63_T<3-\:P3_O8/0G_ -M<(?1%5'I+%&8:-:E;$Z7Q*3>QUY/`\,U'(]H_X;T!AOE&/`:UDO$&G:E`M+N -MV.'O=QH!Z=OJ$?9(6H1ONNMQFK^,!5-1%V+Q!N%]=]J17_^_`[0P#>\SL/^> -M!;K]T"=]N&8,-QO=$=/7!M"61IL;''])Y_DHVJ,)$QVZX-L,W[:D`_GR-A$^ -M4R&\J(;VB^-,:":>8/L9YO,B^%8= -M9C%<"W)?-4\FJQ+DEV&P4=8L/Z)H>]CGD_6Y?-ZH0KE^>ZS9O!^:S3YJ`?>] -MAN=#\Z#M%;"/=M)>63&T%-89$^M>L)%K:C;E,)2G<,TNC+_73YLQ<-ZA&#BX -M7V/\,RQC*91AG2M4@7SM^W^]H6,C)ALC&](MKZO -M\C1?YIH5I`WU`[OM7FJ+J?//AK7J+;%/[-TR-W]V!ZX2>#0/ -M9`V8&RB9Q7=Q:=3SU_^@!AT[9DBGF&<1%_VR(('?[TL8-# -M+QW[X5`5M.NG7Q;.)'#=0_MDBW\)SIMU=OX=E[6U:(<*W["/0E/)5@9MF:[. -M=O$I#=I'?E&.09U'H]OK0\[Q.B>J\+2'@>N(,J:,^54?_5U;]?;S^^>7] -M-WD`ON$Y$M)#,:;GZ,?WF\Q^K"BS'RQ/FVXR]=NY\'6],\BGO9!_+']O&T[_ -M*O\[DGZ7?M=GSM+?C67^C4C^;YK=/K/"%CNPG?GHG"%,8^2A?!M^S)5#OH7DEG/[>/K$TH4E#U1]#.'.TC:Q-^ -M(:BZ2+[#\1W*VT<><L[?17=)&J0S?7&@OXC=,S'6'?*A!T4T9-Y1^ -MW8;_JD99!?90+[R760@QJ1F!^SGWLGTHW[3B'F+)VAB_]"/T^X(8-JA?)7N( -M]:%1MMY0W.N,2O'\UH4-"6V^MTO#O)9]1\^1NU.F#8^?VT&<)QL/#]N>VDKZ -MW=;$:%@UGG:=;UTG=&F.;`?HW>JD"#(:XF1=G*:G2_!F`=B[!&^WCC*:D$4_ -M>:$TYA'AKX/G.63'NWD-O1?3>G4=QXN;I_E+7NX\_O\L7P^L/E8)[]LV:S]; -M,0H1*_V%8.&WBWE8:B^#_!R\:GZ"#L(^V"IB7\+_L>U/NSX$/N[6L']'PZ#_ -MP[L:WK_..?KWJ3]1_UI]5U'2=POHKTGCTE)\(?0?Q8D$61G3DJSGPKO84,8# -M::W^^_55]M_?7D'_W?X'ZK\%O/\6V/K/BCF`]OP!J9_D.4QGV2NY81WR2P$5 -M_5UM(%V^>#VPTFZ0<'T,)7Y40O]-;&02\R;A>R6M+?>E5-9*]J6XEY.]E/,P -MMR\MK#O.O'UI8;VI@;+L?$2=#S'G#\3Y_4?C:X$K6:\MNA:7T+701M>5K(>7 -MV,BX>5^T`?IG@PW#&>GT?#_RT\OT/=UYA>VXY0EGY,?W>T)"R?;+>@<;Z(W -M6?W`V&].+>9^;9*?=Y)LMVYQEX;[L3/<"7/NDC[:NJ)]IOU."L_['1PCB^@9M35=`7OQ2]<0GT:_(%,&+Q+N8[)Y.F]='\NL'-^7+^3W]VKFKZS"OF2 -M5=%H?X,:)UQGU;V($QX7*09+H9\&JVZ`=.NH7+0;%BA_T)#N2,`8[O`[F3J% -M>3WP^YD[%%UB(Q_EN"3^$4+`QWFK_B[#+QSX3N\&\+^FO@+'<^"&^FN<^P&/]0I@.R' -M\6!POW+"[RI;?<'&'M61?4$?W!0#WNQ343=![#NV(TCC]<,6`;[C.\RO3-RK -MVO$@RD0;Y7$2;N=1-3GO&<17C^,YWZ&I&,AP(ZKIOUF>3$HNVN^2"X^2O\@< -M##A7&9XZ)S-QR78F.E5['V"[WLDUC\.Z<!'VODAFMOOS]E!A?"^!^83GIS4PUCQ, -M2:$O@YJ!UU+R@.G/P/\#M"W9RF,$UM-8$D2=[M/0)P/NGPJE(7\'*;P?"@^L -M&*H>N)EBF6[DLL;[ZUX+P/O47'.`QO^ZF?V'5E!,"?D"QJD+I:X;P*=0Q#'6FH[Q1CC6BO&?6R._E^ -MT@C[R<5AJ#^#V)3U0JF\U0#RUAIU.:S+/4=N3OFGA#9N0S_HGU+X;_^@90^R -M.<)BC&V"M7B3@?=ERV!L7=,P%G5[SZO)[W]@GE=#&0*[4===]9!73^!\E"BN -MC#R).MISKM$VI%N$;XRM`;EL#@.7XIY*@YT7U?\3X`UE-U\07+5\(<:S#R?SJ^TG?1+]Q02E,TAWZ`S9 -MB97S&^5@5\/(9:4)[.A45]KQJ;S.U>0_-FG`>$H%T4X1]5FW7\68V0%AKVKK -MOSGKL/MN,.^3CZ>N+'\GV4=9^6^WT6OVC4'X`^0AIM%=0543OY4?,]8[JZ\? -MMYWOJ+`.*M.4=VU9>;%IRBO,A5N`KN*Y$(2Y$`=],0[ZXAJN+ZYIPO8T1?IB -M5AQ'P9O2I[YJGMP\@.N9KW`.VJE+%XQ -MGE?>1>>52>=F.JL40*[X8ZY;=KF,UO_5T^,[ZZ3::._`BKPOVV.HG_&U_F'( -M8_\V=OC@R3W\6^?J8GEZ+OQQ>/7,Y]]XOCR_P1'-56Z3,:;H0N!/[\`/3UQO -M^6ME;VBXQQQ][.!)'[=G&`L68F-;]F,6K@CODNSM>8'3_*,@8AD+W[`]8?[M -M6-!JZZ/P#OS^56C?<,F/AO)^&_N].=L)>CWRP=HISE<#('N#/B)/9T_+?`YU%KTDC\_-!HK]V]>#;%)? -MY8]ZV.TIJT[4'_!\=M>`&5NZJX/COP+85W9\(/JE15^7#Z0<8JS(#E6X0S;/ -M&Z",^JIN%SCY?#6#V,-RV*YRZYW*/HVQCFH&;L%KHH)@EC74TF+W\' -M]=T^A'S^3\O_%91A\1+SD\_0&7!!1?A7_W3XV\6WXKBXS\+V$O;-U/\P7MB3 -M_`P_XR_4.5?_70FNO@C_Z)_9_@4QCTA7,]")=WRK6>>%ZYAZ(9NK2T$?JDEG -M:[3"BM4+XP_CM9S@X_R2@KZG2OW-<\PCXMX@[3_PM.\H9HS=[T(]]GATE]_V -MV>*(S]%^97K[AG^VX:.1MEO)Y^?'5XP/S\J%\=\#ZW@GM,D8,.TZ&(N2;>`=;<]=3W()1[6C7&ZHAC/A^&9G;2?X[?\9!]4VG\.<0?P7B8L-JP3 -M^5@MT!\9C"V#L4G@;\;26T2Z(XJF+L">45C72_#_JVSZQZ0673*AQ>\BN^@P -MQH5%^\))0:R']:(]A3(&Z;-9)8[XI;_GZ\6=]YB\.K*J>+U`FA304Y`F)V]W -M(_HBAO),>T%_%.7SI/L0V5\=X^5IO+R&DO*2TB$;?R(9,WZ-!K1%,B;F90>\ -MVS'LH+C!C&T;#9#^%,`=_9GL(T3J+9C[B=<47:H>*8([\5D!;S+H9\.,XH[J04B-J_ -M0WG#U31VM"C\S939_ZZ8Z_[9C*F)V-T^Y!>KI3G5P]>6WA5HNX)^T6O)?Z?I -MGZDV42=T@;S:2?Z/B_F!?`NC;HM\3"Q@_62C"+PC3*X';>/$;A5C#.&\JF`8 -M6VIW*IM[=/(`[1V?D#ZY%/9KI"/.Z?CU\NG/\>;"MZ(3:EF+Y]H9_M.[&+; -MH2W=A)^I%[;Q^XE0JEY8IZ+-)NBSK3*K2UAX/`'D"_A_$M]C;!&\B^GWJ?K/ -M?;).Z:1:&(]UZ1J,8PCCN8:U93K9/O)UW4,^,U4*85 -M.]7R!Z1:^._K7@LL%/])FR_>IQE(L]2MA>@."-L0HGL#O!/:Q?:=QO_7`OU_ -M;-KONFYVVA?S=`TVVH'OIX'OI]%VX/+LO,SSV6>9^MD::7%TR/GOZEXV,KF4 -MUM[](<$3C@M967=D61SU*8EBGQT++1&CT=BB_:!##8!,MD=7&M7HDJP:%R;, -MV'F,]39Y?0*L0_M#2I6B+O8I4?1!@K9>^`WKWNIZP,"R]$7/&)*8`KDN3>^Q -M[N0U6C2$\9&A/D7*QI`&-QL(O>F".BL'#!?4>:_[73-(;P6EV<_3#$": -M_65I\.Q;I!C?#X;>@C0Q2(,\.`LZ:2[W;)Y&?#>^J-?8[>XU'F?1I!?Y -M_U/@R:CW_YB['N`HBRS?\R9TAQ+JM;,HG#0.UZ9SS'X%EFQ<4KN;W= -M6SRO[M!U-4"`R-^P!H@+)/=^W>_+?//-3!)@PW4F.MQFHL-7>+ROL]#A>:;# -M-IIC:C._C>GP/:I_GNCP/-/A>XM!@Z!%18>A-'385@I<_I7@K"`X"1I[+PY\ -M%1V&N$P;E0FEE$FFPS::ZY"%#A6.B@[7$1VNL]#A*T2'KQ`=8JV?GP`=KAL= -M%S>OT?\[.O01'=:6@L;>GN2C?K\X" -M3?`9F#4^U,A(56E%?I6*QR7/P\SQL1#_4^]+Q']JJ##+U)N$=M9Y?OX*@X_! -M1Z"3=,=L2<.A4NR7_;26L(8<-O/Z"97>G.6IP+J2_)1H"G"F((Z8&"`Y/+#7 -M17^%]%=COW+DN7,J+HSL',QRS5_AI/%%'8PE:.H*C>,D6DL. -M^$>07N>?=B/B04F]SCH^4O[/Z"D*L_QWN']1Z9)QN!'_>&E7K9C;72^6=@?% -M_=W-XGO=(?%"=XOX&>FB<[M+Z+N/OI?3=YV^!^A[H;@_*GWIPTNDG^=D@3>. -MCU87D)Z\'O=626Z%+?ZQM3.2WS>S8^^?5/^PK/_G7-]E??_#A#_T%Z,/+NX# -M=-1T?1@+?Q>_KWB=]!%-]&$YX9#KQ)U"4]P+EL7A3/Z?UZ7>O[51'^W.SZI3 -MVU%]73!&.RG])_@'M\V)YCRQ(8ISUD*"?SW!Q=E>394ZQSL]O:=HMO.!2B%N -M+_VYN#U@W'=>;=/9GJ0OQKG?WW+Y-Z?#'G"Y^M3(O(L.6I,'88?-LI'.?4M* -M_*8V*AN:@/]G+8UW/8UUKG.0=,D+U;BG@CW#4\Y;5AP@^&\[72L"8FG<\ZU@ -MA;RK\4BQCC%ZO,Y352_CBF,_N5$+T]P&J2[.&;.=X6,VTO-KY?E^L`\VNMFX -MQ\/ZTZ`+9[]F?^@[2RO$G8%&VP*V^2Y8/.76H'^K6!JU^31]JXS1+]]_+_VE -M\`9P#R>`F/RO;?;WC2SKPYL(S=1VB/Y:Z"^+_H_S.L3M,^HA9F$>[.'K"'^N -MK][+6ZD_[]#Z]FU+]E%]UI%X+\]&_3MC]F\D&@X13OWL-V<3;VG'DO(;M&:" -MWVOD\UCDIAF+_GS$^++>GQQ_/#I-[2&^F;]=TQV^I<3#GZ;\ZOZ -MT(@G$J3R/2/+A@BG:&>!K@,WC^UP);[O)3B9Z[9&7J9\AWP[8AG-\=+X3^G_ -M>(?"O%_&&!MCZG?^(]7UD/PHU1=.OY&^+:4\;=3_X.^(?WNF/^''V?1YR%/$ -M\B,]^Q],_0D2?6Y+\B?-A-_ACLQY;^_"?>21$<_7OI7O63F-UK#+>:X:/A'@ -M886PJ7F$[_WQ0K-_/\U7@I[/)-%SX=0O1L_P"53SI7QJGH;?RYRH7-\D!UZ9 -M;FH?XV.>,^O]V&F$CT/"2HQOQYQB_7/$CI+?$SXO+_%=S?\87M:WE&@<\PH] -M82F-FWEN];R>HNQ1^XXQ7M;^).;WC>&)T*^M$_.RVZX-_I/I_8?,Y3MVC47O -M06H?=Y\VN;U5]#N.F*M($0/I6>I?SA-7=RG\E>^L?)O368;[^*/Q3]MHW#$& -MDRRTK4])T_\QZ-MH`V^&IF\CE1X_FCS>^DG0(_Q]T=]Y1(-YM/<&31AQ_.QR -M;276*]J:9&DK-'DB_4FTET+WZVZQ-S?)XO&7X. -M]>==,1'Z/TQZUEL>0_Z^,7H>G'E-O$YR_>^=>%WONYD&2$C=;-;!E[;*?'S$_-ZP7R)-WZ7)P]\?6) -MMCJR7O+W4[O`I2/W:"7T#YOP5SUR=5F?>I_D/N?D"UO -M3AJO_PEY(L>?Q[DCZR[9_[NOJG4Y'OW.3[D/,3;]SAZYMO5^K>L#--]Z\03) -M]HXJZ5M&^F@+C5U9UKE*Z#2X,XAX*4>OJ#@L'06]?MPE#?%XYTD?Q@[X=$N= -M`+S8'*^ZHZ!3WL^3>77R?D57"W@YS8%1'M^:<8^F0-/E?!8$=?F..,'WDJQ` -MN2);HYS3N2)XVCR_!HV/1]\?.;\8?8^,-&CPL?^4YAAXNPGOA2S+\5[>0HLL -M?]298?\QACRWCFDECVDAI3[9EM*'?+*M!,WF.,?0A[(SZT,++/,S?[0=I9_X -M+'V*.*Y-/VDQC4^+!5:=X]K'QZJ3@0_.9CW:JC]_;=$^?UKY;Y\X?['J=\=9 -M%AMT:?":^BO+DFBS[LK&)-JLO9+@/0GZ5/S'NE=;;/_#^,^B*XI/W&"BEQLL -M]'+(]L7H90;QG#4F^EACF=.P[=KHPR7WK+@?D#Q'Y6/A-\9\7;R-%Q?:6'9/Z+6==7 -M_N;68-4AY\:J.=@GBYT:WJWS7/I^P"$\N)\]"/F-=P9>_+Q:__W(QL%LZ:1A\(^SO7?*_.S'`VC'Z6RL?M[95%5,;>V@%.5^=)M& -M9<0)Z`*SG4/4;XSE_5'"-TKX1@G?W83O;G4N=.F[PR/SO#^AOA42;I^1/!FO -MCPO^G_5QHOV[`%FIXN=7&/>Q8!^SWE'`F8&6Y=(SQ:?M&NXIBHS:MX9?RW<. -M5XOV)5%=''X5:8!2)^X7M"^)Z:+!V[)IP^Y_XWAWCU)=F_0O*HNCK$O41*J$ -MOVMHVWW1(=(7A^29\.J(W1>4,6?XO8;]A%[S'W4[Q9E$;=X)N)P]E57NH.ZP]FD(RW* -M:M*K*!7M/5&'R0#VV"3/5P]@W@(?,DC?\W^;U>ICP3+17G:E@V[GVQF -M_S?ZWK]M3@S?MO"W)OJ&-NW$2PBGKD,T1^:^AM+<+_=1'5>2?9'[Z![RM]"X -MYDA[45G7/I'??4"4=1\4-=V'Q-KN7O%,=[]XN;N-ON^@[Q'ZOH>^=]'WU^F[ -M1M]M[M\!!M%069Q@1'V4WDICY@..+H_N(QSQNT34R!AE6?+-GK)(YYP;Y;F` -MIV"^WT;?/`4>&6^MG.K37S1/^"/-5!=CWVP:>ZHS.$FHN,+X#A]FOUO#&8B. -M%/X,%92*]@VTOZZD]#ZJGWE^[-L#]*U*Q@_"^.-.T0&:FT:FO\'+BOY"A%>( -M^M#:71VP(Y;/W;KTXP$NCQ`N27F/J;PLREL#'WV[BL'ZX\=8_C/,`,&D/[RU -M/9A'91OE^7]9-"3[Z^_"[W*"FT?T[12-\O_H3T"LC3K%ILQ]?747@Z5^SKB!]/<`+[=O5H/B'Q^9YIDBAVV]2/5 -M!417:X3^ODW&%D$?EVE-1#OS&7>[^R:]5M3$:X$KM8&X/O;RB&.<" -M["L@X_@#CUIJZTE16>JH6Z>_8Z\,>->'`V[8=1%O)]\:V`<_G'P<[/_BEI;+EH;Q#_0-O'8&I():CRF$Y\#C<&N -M:<1::2-^=X9CM6TF6(6,8Y!Q#'T._Q_`.KPW'7\;U__WF.,1&]ZS],HW>'K9WZRUCOT_ -MAC">Q&\6:9)WS!4J%HY/K;L^GYR7PWMUHA/X:2)%'W-$1<0A5E.=C?H,.6?$ -MFT4-]75M#.L`/K8ER1%C(O*LRX1H;']).2\O^BV?\M -M6;X*U[+B0LPCC>>CAOY[4>%"+UP?A%XTH_'27 -MY#=K:8XKHCO$`_#Q7@795,A]H?&,A@E_AV@HAK]V6#3&VS9OV+V<\=Y,;:4; -MVS']?R^,/[Y&VP:>^%V8!D^-UY3&>#HM>,XV]G^#R7AF',=](BB_Z\FIEC<@ -M?6G#2WIE^@3NZE)JX]3.*4`,X]R+?KOXVVVQFGMI,=?$]W+HD1G06*R<]91;[ -M7:_ZS*#WLB[ZBZA8ZXDUVX78V+1V;.Z5BD8E7_9*?;N7YO6W3?S^@6P#Y2KT -M'.9[AD[>Q[&9>W^GVBJEMC32R86KH;B-^)GQNY#H9@?1"_X?(=Z*=`^G790: -MTRQ:55D@;077@(>8_R",=,B[Y-9]-5M"^8Q/.G%Y[4/^JY*G$ -M`Z@^XBRBK&'C'2U7T"3?>[#"0#O*E[9W_TS$WB(^`WVE\W_FZ],)-PTZY/9C -M?B%UI08]BW0BAS-*.NW+Q(.VE+XCM@2$>+%T$LG!Y2(6:+(]$7`ZM]">>M-B -M[*7!-Z&?N]D^D[8/$\#-:<@KRD?_C//M3/!L\FY7_[%+N81A>WJC:1"42'?2;K=D/\#/44^ -MHJM[^3[J2P/8M^CO@[>$6^^+AC=O(/Z#MQ[L5+\HYI)\O2)&8QY#?$SHF4GG -MGP/)_,;PT;3*1_"1B?P_0>!RRJ3>CAM;S_8=S4@>)ZI37RWGG -M.6^[S*N)_D1X2^UU=^O[A3=@&]A89>PQ$)NDG.JA3A_7"5*=\.8EDI^[:*WA -M30_\W]>>>*_J`RY[ZSEE`]I#O.(CEO4:?2MAF+_FL);8O1[5XG4K6PQG..<^1OF?V=9+Q2Y,:(%N1_>MS5Q -MYV8SY9OK?<+UUIPU=`(E[R&GFJD/@(&X(8"QG6'H9_%.DJ)UC?$"'[E>QNM7 -M>+D8_KL,/^^L86=(QFNC\?[5&8674>]?N-Y_G4G%*VC!ZV&&L>=,*EXE/'9= -MM/ZL]8*&_[^E'GZGZM5JKY(NOISOC/7]L<3\N:@<_*="1!]7^'T6<694EHS. -M:;VM=S_.\DC'[<)>0-HJ"% -MMCT5GH?A/9H*+XFN[F68JZB<7;V=IEMI:QK#*CF=3%L!KNLR\'%[]-;U\.OF.;7+>'?H>W\*KA?Y3L&!4ZE]S^&V%AKT?RK1]RK9]U1X1QA>RZGT -M?3=@%C+,VE.)ON=8^OYKAE5Z2O7=J)O+==VGQN^[L7Z6T?I!W+F`'(=/4_". -M41&ZY>XG4JI8T:8_[3X/4=B5=JG0JN,]2?#J\5 -M*7C=9M!_?S)>)7+/D=#?P$P,BC/U[13'V\-[U6F"1 -M?'LM0QFG*A,$S;A/I^`^@W%9;,'=Q_:7)DEKJ?6RN)XS33WHY$AAPT4=@A-# -MG2'630Z>(%U'P8_:!G7]\?7PU3E273$3,,KD.P,&+$.?A<]UB;3O*?Z_:WAD -M?[,X]ZK-?28%MX^-][]/)..V!N6WIY;_3^/\QU)^++D1&NO]F^.I]G'L;TBG -MZ2:XW?7MZJW4-Q_D]7\\(3]L[N,2OQ*Y%DEGA7V;QWK'<35NT']K61_YZ:-\ -M_YWR9M*^Z#E)+_FQ%H+OYKU.D.$#;C_5>99UF("$IVQGVT*L_]"WH#BWMY[^ -M2-[%'+P?^Q'',7(SK&;H$X0+]DW-DLXKY5MW]7+<\FEL5;VGC/A'Q\:N1_09 -MKV<[2E"E4I_!31(GV+C,Q3=C3PN%K>"R&.J-#`]^C_ -M-J]NSM.9-^JC=L*::+_L0W[LD:L-TD:,O"\+]A##_J4)MI$W0'E2QR;=?&1> -MI2;OQFL/%!?M;0P@1OBF;L2G;QRU@T@;4IT\,TIKAPN9]=^CJ?85,_UCGT^_ -M8](^2#12\(B:L]>/RO67T6[FF^#][M`UMG_A+WG]?TGM#QQ);U]*M"]MAM(N -M;."!]R]#S`^ZCK!W90\*[&S[[S[0HG_T?E:H?4(1OCM288X)\$ -MEVVWGBC.HN!3K,FUV*!Y9U4%#/L9<-E*^]EP^P8J_TP4=VN+LS;IZ:D?LHDW139>^'W"*1OI6I6^Z -MMS+02F6]68UZYOE+WGN8Z2=E7[U/"T*WHGVT7+OIS@ -MOU&_NTF?Z`9WZ>LH77J0;3_[/DZ,%]Z#E#HX\8.XX?_$^8A7D`D' -M7>JU\JQ/GG53F:[WE9R2-E,[]<=I@\U4G:TN?UC!KOHX(2?K93_5N/R*<2O^ -M.'$N`/G2+.63U#7E&1%BN'0N46,&F?[OB#EXMZ;_@-J$C?87](<[::MHWI'6 -M<@H=OSF-?:U.Z@5IZ/'NA_2[8'LC';:9Z6HRZ6]X4_Z?O\O[O]\J7-$6=`CH -M%S@_!8W]*>O\;TB=(@W\QQ[6W:Q[((_JQM.U]4-N*X_;JDW3UI]Q6SO3M(4^ -MSC:U8^TCX3"8+@^^[]Z;2_4ZFME0Z' -MR6/@`-UK)L-ZF'4FVG/*LW%U!ET31UT,V6?KBRMS*\, -M;)[U4*"S(*SC[8\@SLHES_7'\9;W*J*Y='10.`8=3+?0`?@+YL;'.6!W)$8WR;!YQ./_TPO7ZESC\A5Q+\89J% -M/]0R?ZA@N^4,Z@/\@IY;Q^O_@U3;HI)Q_LA4H9]6]E^OA+&G7?D6H?Z37+\\0WWX?N0+ -MO5_];B3^ND;'^T:`$S'!:6$X`X=2X:#L#BI[D.@TQOT\0.7R^!S+Z!_&H\W2 -MO]4,=\9A"0$F>`D#*O" -M-Y.H2>!TLA04O0,BHHL>>0_%TX`9 -MF"&3'WYT@TP(KL+R3U1.H_C#WOK6X`:/7XU><+,G9*ZJNSKSS6\FOG?'>[PD -MW?UU57575U=U5U=9^-G'F6$[&-?/7P[-#]N?C8*7AWG%3'LQ\E,:\5/Z*>%G -M@7?>*2]IE08>ITG$&<;]6OIKU`,-S]70^>]G(K=)HOV[XS.Q?Y<"_AKLWRXV -MK]/-5G;.89L[\?U<+?M#)V,K@;;]7!Z=F%W`;O0Q=A[71@;QLNJN'VG&(LTS!E3".VO -MY?&?IMAZ7L0[PWF@<^"_E8#C_C;`IPWP:0%\6@"?%L"G!?!IJ=7EX.'Z_Z?1 -MZR/R?N0`Z,08MP-]7?;^ZLYA&PO6>L3?%7Q-*^8^QWBZ7S32_>()>?\/\`J> -MYOJK][!)<]E`WJ#,LF4OYG=JL?@DT?JV?QK;_^'=X/R3$G\3^A`N6U!IBNA_ -MI/OWWGCW[DGZZ7#_ET_BW]^;R,<-QP+S>]5D\]RPE2K*;)%CV&N`L3306$Z` -MM@I;94/_E%,R__$G87?.J$]5HHVM\/<)O8<_X]#/I\FG3]-&K\O -MUOG93=>&[SI-.AA(TW]%T)0HO[,I"?H,/*_8%!7C(L;"?87,?WIR=+BC/^0I -M\FO%L4(8/`[7*/C'?3*^?8[^4\A'JO"9\B(?Y15KW*_)1CQCX;)-T#&;Z+CR -MD?X.B/#&/(;K-7XWJ?"[M&]`_HCS&@O?&VP)[XP+DCB+B'G^\5'L_1GE/\I^ -MY"\3T&*B\WZD8Y*,__-1R)=(C4%'"M"!L:-2Z9X]N?.2B/A/'^[+6SN"?*\# -MO/?^:@7([>M`!OY+&].TAQ++WZ&6Y3'@Q?(_<7\8'1_!O8''VVHU,O95'*ZB[V[,L#N^MJ*:^W^DRLS+$*[&@7[(6SJ$TW -MM`&X+8QE!(S*%)M]]8JV6ZEN9\\PW,!Z)NH*J&Y]SS!EV.K.$?]SFF!_LY(^Z]'Q"XM$'1@3+4`VNX8(VP.Z&P/D$_? -ME0]@#Q)M.L-C@T7?K_9\$)Z?`..EX/A?VS]_EM0?T%=R.8S5'\D?HND#J3>, -M''^S3M<_R%2;%^S=#/G^YX/PV(HQ]S]H8_HA.KY$KW'R'LS-B['&U`US>;RT -M:W`L-MS0VO/,BK8#=$[?_S["R`R,86P@'>J.PKRS#7-;EX/N=/,*BG\);7J- -M,_A9/K8YAN?E+XHVDZE-^_OX)D?],\8U1YO\+)V3KG]?S`G@,QSGJ\.PTC8( -MXS7^"3K_AC;=ALDV@-$ZJ,RW88PO"^EM;@Y['MAQ&(_0T0`Z1X.)/=5@8;Z& -M`\9YGF[C2D^/<;/GE'&_)\5\I`)LD(`)YL..]Z/R_I]P8/Q]FLWQ(L;#'V=S -MH`UD^V<-8QXZ&JCL[_'\02E4[;A_PD]\OW\?O8\`^O\\A/'-,JP.-]:;;W9@ -M_=U4/YNIEW&<5/2-GCC+A?U;7Y[O0OQ59@-=U>;'<=#GGZ_[C]`['JQ3-]S9 -M:@'<.^BLQPWUP_J(<:6_@.6)NRBS58/?`W96$1!]+ASN\WKX!GV""*[7^G*9 -M2RG!6&RVCN!0F?7O]/!@K)\A6'TG]N7-UKTW0WBE`,_';2.PATA^E,*:JZ?[ -MFHX3(;EB8G:,R[^U9PW4DS_*^A,X?Y-;UX+WP[E=Y#"K/#SS4`#S4 -M`#S4`#S4`&/K`1[S`(]Y@,<\+I;2ZEH;NI\Z\![&C2U3$7>-V0(]AGD-V!?H -MOAZ$UP'PUB+^1.OZ]T0NQ)/)P:VQ>$\:%S8(U'QQ:99W# -MJM?-8<]W=@>#UJM#7UC'P=K+P%B48?$CSCDS[*HCQ7BP(L6\1',K,T!/J9A6 -MSBI<-4H>O4G+^QE_@Z;,L*'O"I[]/R+C'[^+LF.*ELK81?S6.O%F$>/A/JN& -M[XU38#U,@+K3]"Z7Q]^3VDGYM!3:>0WX!K3@O)DR9JPZ!--\G!FTGFX5W=E2$AUVR8&P1_ -M'V=U3,$SNA7RKY)_*Q=/3<1YA=AP'BUK@4\'J*[VJ9N$0<6:2H0 -MKM+[L\!VVD^.E -M7VL'#$G$/SX>0[^"\2JE>[:>XR'YDMT_I1)Y5T7Y1GM]Q_%H'2;,_@M][X\9 -M_^KXL.X4L]Y]/'Y^$=S?$==QA&L^[POW^LPP7.\C7(U0#^MQ@-=#G6OU7'[N -M@;I+0,9_/\;U`;Y7E\*S -MH_N/Q:8C3^8_.89^E2$Z[/4A.E83OI8(.A91.1LNO\C+Y\GXMT?WY:7&H&^D -M7*\CR>_U1X?WK]CS#_6^J^/+\2V4T&V5-^0XVS?,]==3#%RJ\T;Y_QT-Y]]( -MV^!9VK?2CTH^/-T5:2.LH#9]1R0OGNZ*M!66R?WOB*3G=)?4L_$<_7C&NAA\[6\G`>TO-0:#7/$-X^K<*2R!0/U(!O;@>]N(-G8=WA? -MGE5YWN'+J.$Q1=!N6$YMS/+^Z_!(<9(CYO]P_/C']N]KJKB\R366%P!_CR7= -MY?[#(A<0[!F7ZV#/J`1]NY9T\G+:!TH/XSMRC=?/A/H%5'\'U5N0%N@?XQ\K -MY@H'YG)+9^>[$N4-BOG^[5"(OY`7VD'V*H1GX%!B^\3$3'XU)T7#]\/UCS$7 -MZ@J1_%MW*'9\>XSM#_1?1?I^"?3-(?H,DG[XKCQ71;IX_'B1JVYT^06*E6\K -M4*>\)\U:/AC,CEJ?X?7W[(FLQ[K!8/2Z#IO_@['S@R#?IK/"UEY86[^@/7#1 -M03RC+H1]K#!0G>8`VJHZ$\7SY^O_8/3^E<_P/1_>_"LU4>=QOL.N"'OY#YWP\DMN>C^1?LQG -M,0*_P7N8 -M26'QO*:H$W5_%RGG*[`/M(OTVT.R/?_U&[ -MJ:D8KQ]CE0>=B?82OO_MBR\?QS/U$M*SC_K/A[;><2KL;9C+OLCO2+,Z?A)! -MCSY^8*%RK@)M*<3Q;>JC]VW1!\CZ/I2OC.2KS$>';7=1V\#;@A[1!G.@%`4B -M:4HDAYEN?;`8ZT#4BQPXCRC6ZFRC;1:TGZ'P?"OQUTW8^?_;\?E#CB/JGUD\ -MWNPYKH?^U<-T__>6R/N"<@YUT&M!ES1CW@08BYC7[>DLZ\[9LZ`7 -MGY#Z[UNX#]S*SX14W).-2J6%_;I3>:E^IOK8%%?-/7@'A7=(,UQ3)SY0-=98 -M,S.=/;S+Q/ZV">_U&+LED+6^?F8JJ[^,<=RZ5Z]HFTE]^W^#9QW?)&>+)S$^ -M(_$'7_^_B98?R*/I-#\FJ/>S0B_F9XV6):B?Y"343WK>C)]_2)ZO@OY[[@\@ -MK[P9&5H:K!L\`SU%>N.SY/.\%OH9"_H,\M-I:&N%M>?-4(;;]U#[)ZG]'&CO -M945>WPTVGK,:O\/SK=5T;EOZ)O+F!64OE.A_!JR'_![@#DHOWV4OKVR -M5WQ[@+Z=2]_V[8W%RXG/KSOVQM9O%"YWJUI2`+:1E6E&5C_PS!"7Z7X9'](W -M:8VV9B"O,HO57Z3\5],.L9^Z8N7SFE"BE6/\\?SB>NUR<,L5V0;/IT1NVP=Y -MCN*E""-"QTVDW_9WZ>)KTYV'/'__N&OD\_>.KL3\887]PEZ\P&'_7JEVYTXJ -M=Z?9-=3U361/U76)\QS4]?>"KKM0*;-UD*[K))OCKBZPQ[_[OU(7.ITN.1+^V>/P`7M@""M^YU[ -M8NM]7/_=D_C\0C%/QSC>@:&KR!M5+=CW/1,6.C)A'M/9DEW(NVZ@Z2[Y_@_A -M@UZT?$OS_EDSBGW\9CTZH"?V7E.$T?N=$TQ*N6^,<4:[ID' -MS&JEE`U1\]^97'Z8D-P..L5#$F"L\SV^.UX'^]^@3F&5>XY#X.=*6.L0=ER?0.+\A/JQ&82]Y`TZ$YT3P'E>T*+? -MPZZ3[W\([S%L`1^KXS!6[3163])860)H'XNQ[-:-Y3]1_>!N(0-#8W.)C\U" -M@G%J=[RQ9II^K/7T1H^WZ/-NZG,-]!D]UJ*__K"SD=CY"F/>_^V.OWZ_TM%= -M0G2SW7S]-%C`/L0WGUY6V*'"[_'6;\\;B?(;"]T)[%5^OHTP_P0PO01S(L%< -M]P;J',_Y,]FB:89[G](.LH6@8Q155L#/&L4&O^=59K+\GT6U4:9&M1GM_F1Z -M(Y9]',+7:`CA>X'.JS[?%0/?$C4!+O'G9_VNZ/%+9W;`W=V"YS>(@]D0XM]W -M"8COK12.?G'1V)SF\$?;?IZ'N1\%_>$:+O=JA?3_7/ -M2_H[\-T#YL$N\N;PO(#E#LS9ZN"Y:QU^7TH5Y8[3XUO.RZ\&R_IT;0,82Q'S -MP*;+G%4I#NTBYOP;@7[,CY(*=&#<*L78YY3Y4%727]*,9YR8^Q?SKQ]D-[DF -M\7SC?9HM=UN):#?.W6[M4E^T5F`=6@^M=PW>.C'U9B;;:4[F* -M2TEW\+>/2KK&?V*NW?SI]8#_XFD'H1\#]7V>R^0OG7+_MO\Z_OF2'-]'=>/_ -M4QK?P=?%^2'6+]/Q5Q'5GWI=\!?>S6+L)9/9YLB*.!]/9YG-I8^QV="NV?(4 -M]+U,O%EI@F__(7TWX)\OVUW']8+7#D593@3GG -MIH!M'TZ_6'^^U"+,)\[U>!-_$W')>1;ZG4@^$.M>P[L3-H"Z6'98/%?,^6=U -M8%Y8G`<_S,-:FH=NTLG=K_&S\Y:^8-EEQM:UO!_<N4'DGLSEWVOQ]X=. -M'5_L)'B].^6Z*_1F\75G&]8G0FOJ=%=H314.KZD_\35UKBO9,_YL8_;?U.?F -M5_."Y..%N5U. -M+1%EIIVH`\-Z@?)8^EO_CECRZSMG=HE:CC"#P>)ICO'%_%X[.R(?A<+C["JW -MN,J_@_6;RK0SF1@3$]H>H[:U.Y+/ -M^QRV_^\(S2^^E7F2?)^I[!WF%;2.M_>W+?=^B^1W_K[02_ -M<7O\O+!A[__TWX,]6H?Q-TAON!?JC`I3T3?I+/#K++P[)WYEQ*_V!'`X_V^/ -MGE]%IW.Z^)V5E9_#/TUW"Y]OVY>'Y3S?,=Z/4?F1;;'G*.']W[80?2YFXG`> -MI/Z6;1O9OG1OBR_?$4<\XY]._>5O0YVVE^O+M:`OWTZ^^UG;4-8S?I^UMQG? -M`)QWHMT_G]Y17VR/31?7_]KC[^_2CODL./^DQ&4"X=+8+G)PJJF*AKK)"X\S -M%]ZW&DB_7]X^,K]S^I.`WZ6#_QWYE%D(/IY+/O4X[K5JX,>LKYZV^/=W>AY" -MV"<)=E-;^#Q\,I?T_S8\FQ'ST-$L^.TGGCHC9IYY]WHJ\-UNVG.E>; -MX$F$\R;!*6E#&F?#_JIY?FQ^Z?[6\/QBZ5"7"_\U5N=-[2^K-)1H87G,?9TW -M1/]XKH1]%$%?DUA0O0GV(SU]UNQG-'^YTNY -M2?L4]$N#,>UN_#L=ZO1XCDF`Y^]!]A>GGJU`.?""L7M6#\C_QV@N:UM@GV-3 -M5+T\X/S?$GO]8^PYY!$+KG_RA_U)[\/=0V^+43`WQNY_: -M:Z/$SY0$?M)_N*\YA%\_X='3'([?:BK?VSP\?G7P\A,.1K2$4&O6/R(T,?JM\IQ^\&)X_85M:_=^B/UGZWQY3/28"`: -MEDK_-PY_+*?A<8)]T2?.8&7Y(U3^,93S-R(9*H^+TV/6*N5=T"#@WD5O.'?J -MOLKR)X><2K'9O"/Z;5/82E15/%_`?DOZ_HX#O'@'^]Z0K -M%NC@;Y3T>R6O"?BS)?U;1D'_EL3P/R7X[5M"\)^0]%/9"[DWQ,M!U92 -MGVL]X7)@.977>>*/#:??$^*_JT-E-O1]K2&;L<0SLOU@\L0_?\7Q>F[X"Q=$Y)O)YH$79GXMHK'"9P:P#;M_CM;NZ^@+]#%X7/TVDTK -M6HULBPWOR)W$[^O@>Z^?^PSN3G17'G/^FT+TVYF]-=N<7X[^S+7DRV]OBF^G -M/3Z`_Y>K -MO9=LK?I7A4\!CMUS,';K([XY"]\TTC=.^N:N5^7X6;T3F'H1[TEJ";8=^V.J -MW\1]PL7;""OI(F:HP_Y-_`[0VHKVUU;BN\%-H3EIC&@CY>?'T*:4G>?W;'C/ -M/YMLN['R%\=]&]G^)9O$N*^-&,.Q>)Y, -M8_@]V4_IFT)C".TN1H[+_41S[\9]>6LCZNZ3^L_&T?FW]S -MI?RNI/EY[8S[DFOUBE9\SX]RZ$::/R/1P("7>XG>_E?D=[W<'_P_B:Y3 -MK_PO9]<>'561YF]"`DG`L<%&V96!3M`Q"3@V8W2R>UAR+P;3"0\;"!)YI7DG -M$*!Y!^010H```<([,Z-C@DU$E[/;,QL5Y\`*([O+>IB=.(>SBPZN43,>'E$# -M!H;=9-ZN/]SQ/I^4^K8NS@+ -MKCH2KF-G`L>R([J.I;Y$`XZG@6/^$;&'$/Q!N?Z/B+M0HPYV5^FX?P5\4@R_ -M;<)ONPZ'X_X+?'LYU/XU;S^$]G.'8]/$>$<9)?^'8^M/(P^W2OX?%K8+P5@) -M&+VL+=59JLG]6%6*CK9MV_!&KM3_A\692>WKHE[%_X[#^<]A&;MUM4">LRR" -M[KE[R+[^:CUD$M]B@'\RX`\CZ7MEN[Z_MAX,I^]1T/?DP6CZ -M/@2X7SEHG[[^@_'A_PO63OY!'7Y%RG\$_`ZFSPA^*1^."/B7`_X[!Z+A_Q)K -M\?(!^_`'#UCK-Y('E?%[!'A0=4#7<>)M>X'C.>#H.T#YH!1;=[6@BL$LSP%/ -M`3:5]3^*\S'*>7`HVK'>_)W4CN?Z1]Q/9/?7-)[KPN1/RMU"\.C.?BEW;:&S -MQM];<"[;+]8.T2K&V@KWB_]MS9N -M,\OZH2/VV_>?'/MC^V^2[O,QUY5]8B[J\[+U>PGMK?NL\[N"^Z+'-^KN\1BG -M%N,G8OPS:/?'&=^[+S;\O?9/X>F/][Y+9Y(N:1_''76^/GB#$^U7OM -MB?&_POA7]HKQ>V!\R9_6B/;?R/J?>^WA5[\WMGZ3^]P_2_G?*_9_KI/<+JV? -MUZ7Q\S^)_UZA^_HJ>1K!T2#QWVMM?SGV6LM/L\1_CWY^48BQ+^ZAG'ZEW2A7 -MZR3^>VSBOR?V_BGWR8T2_SV45SU8W3E`'=TO1]6X;E)*1_6C.B`,SO6`4]VC -MW\V=V;KAC7>D_.^Y/_NX<[7='\Z^'87T\BWDS=^OZA>;U8U['[CCKOR[V^I/R,0CCGZ_3UQ^-7R+7?UV< -M_->ZV.M/ZI>>&+^L3E]G-+Z*\;T1[7^+]MPZ>_+GJ#.Y/V0V@W$?:$?N:=LN -M_?SL6\!V81>/P1BF*5D>7T(JCYE7E-01":PM,:>4;;(9'O;_$9'VQ._QKF/= -M+O/[5?\NG3Z5AOW^#'[KW67N)_L5;\"GN`,]>*W+8"`R/Y?BHA/9/WD75?/( -M$YZCR?-X;;^FMS>'WHVF>G=-DS>KWW7GM3>Q?JH30K^E__>F.D9\C,?9&(][ -MJNG^+KF:[@"[*/[AZ-OI*N7[4YSV!TFC\_T,GO1D>N/77GZ&?Z>.?Q;CQWGF -ML[^Y`/O_3AOU3W9:G\\N`5]3=NKWI^7@:]<.V.N*B_NT+Z/]\@[[]D5PA[E_ -M(-?0.,!0LT.'P8.Y_#N$;ZLPOSK-J6G43["4H-\;@E'XW1-E_><=PGYS\#PI -M"_V_P_Q^1\K^XX"OO5:'SR7SWVOU^QW2A_W0?K)6U(V)YY_4U\9>?ST,\R=C -M_KFU8NW1_(K$OU8_HZ;Y;\KZA[6B!D.J,UV3?=?1-Q!]=N(+.K?'I\^G.(<[ -MMUVGSR7,%=P>3I\/9?W#[2+^@.D*U8Q.7/ZWQ[G_P]P>P]SO88X+_JL1_F\Z?!HG_MG#^R/J4#=N@,Q.9SNRA -MZ\Q[C9_Q;K.FSVK`EKE-I\\RP.#<9J"/(NBS'WUWMMJC3^O6^/29#!@"6W7Z -M>#%/_=9P^HR2]3^WQMY3[I4^[JWFY].E./OL`QBJ(LY)!R7E9?AQ3GH"OE]; -MS>DA51'GG_VQ%L_5Z&<5E8$9S6_>%GG`Q(\RMCOU-R#_U]C[9]]+^-? -M:@1_R?=/D/)?0S:9B*>AW_@8'I^@KO<`WA>^'V:2ORSP.DK?_A[?=FPQSU]I -MW1+;OY?G>CT!W_$M0@_X(V@\E=&X##2>!!JO9]_Z.8VOA6A\"CCYMHB\A,K` -MWS5OODUQ3;VY/)V"C*E;#'X"_VY&\'.]EZ^Q'>*4BIUL]7*6^$>/-+QAL?>--1#OG?+.C?W2WDZ7G@ -M>7XSQ:%>+>C)<_%8/^[B-LX'_S>'YY-0_7<[]_O^S?;S8XAN"T&WW,WRW/?K -M`JIE0NO%Q>#Y@]3_F^49KG[&-!2R>K=*OPM)4UP=8@P!MY_9O7VE_UJQ/URKC(L,`CTZ:,H7UVJT>E3R[X9Q-=J1T')ZR+O,`]] -M%:SO$>1+R_&G,CG(490NBK7@]:A]F\560_ -MH=_!<1#STGJA.D4:XVD"V7^;Q%E:.'ZB7LPEO_BF=1/5S)'CZ_#]A,'7`^/^ -ME/&:Z&0&:_)\,5;-IGL[/T^@_6^3]?G9.TO$V)F;Z.VKK(",9Z7SLL^6BKX^ -MFX3>ECIRWQS@O]':SJ7Y6S>:[R__MEB,G-S-+W.W.NA.G/R=[>Z\^X2OAGW -MB>\-K&_G>H'O(>";%`/?K_#ME9>C\?T,?1=>)EDK.N911@82^'L5(UOJNTMO -M_)'&[F=RL9#.Z,$9%CG\?8_I?I_N(U355F -M4@WMYJ?[KQKU=/+L423SF0Q.CS*S^<`:7U%`J3Y*T?J@V@9?IG`\K!`P-Z[`_*8N/]6'CI?$U,K3Q -M82;K#SIG:V)]:(5:SZ=4RJUA^]"?J)X`Y<](?#8!G['K1`Y,'W>5=KL[[U:: -M6V5TUPII/&,^5ZKS,S;N8M!P,:>AB_.ZHT#0<#>GX7LO0?[7$@V_":/A;,QY -M:6U\&JIQ[!.B7_U::__E>>B;LK5Z;.4$Z/3BM3S^,(/[+TXEG_O_Z,M=&]]_ -MX?HOSOP_POQ7*O7YAV..BY5B_L94UR@C#+*_I3+^_E%?:3U_3XF_8?Z^$O]* -M'?]]`\7<_23^E3;QK[01_PN9;5^CW]]>`ERM:\+]^S^@_21K?RM9U4+P.=71 -MM.X?#]&OTE-N%SVX!O,>!+ -M6JW3SX=Y.E>%TV^JW/]741V<--6X_@B^G9+_J^S!5[\J/GRC`=_<53I\N9C' -M&P'?3]">BV_[*H)N<]'N6F7_GH'@ZUP9'[X?`KYS*W7X')@ON#(DA7IGOQ_BP%NT70^W7>?L*M)]:9B^>F:__ -M9>;\60/^5"S#&6$$?V8R_CC`GW.PO57VK2>"/T^"/X\M"^?/V1OA_/E[?'?7 -M'\Z?=V^8\Z?5;X\_3O"GT:_SIQ?H5>7"IH2 -M;,,!V\&E\>TCOV%\K^+@]YPT;B[&]2XU/U_CZW^IQ?J'S]UGJ9`O-4*^WF#R -ME2+7/^2K;0GS>R/7O]3_2\+E9FU(OH2\O6TB1U;VL7^).?S_"/C'+A'PYT;` -MW\+@5P#_7=CM+O9M;@3\\^3^'P%_803\6^\#_N#BV/N3%[$4M['&:Q<+6??B -M#CVS6M?/%=27HVJ-J:KV`T7I\N*^F^3@'7SC61Q^AN,JA?POUNM]2?FG7)-Z -MR(]CL3@7,IY[]\5ONRJLS^FY_%>8KW^)XVG`&*B(QK%9XE\1K@,4P.?GOU&I -MWN"=QM0QFK'^0N,#"XD>[49Z+,=XN17A]+@\$_ROB$V/L9A/J8BFQ^_PV_9% -M]Y:GPOF_*+9^(+I(_5ZW2(]C(QWT.=I7+HJO'[PFX_<`?<=CK,R(.&%\ -M^KA-X*?Q%TC[)P+VS6CO*K=Q_EENSM]NZ*<3Y>'CEV/\@S;&]Y>'Y[=0;C#E -MN-#^5XIQQI;'CH/@^)?'UC_\_J\,^)>+=2GCZL]"WKO*9#X3W271.S:?%_A^ -MKL>.3\&:N5`F8F5IK:4P.^)CP-52%E]_U)?I^/7EO._+\,L<170:+/E?%AL_ -M>F=#M8@C<<3IY_Y_F;G^(AH]#!I=6:#K)Y[_"]ZV+A!Q7\:[';IGJ01M@@OD -MO<^U@B#YC\"I88$]^\*_(/;]6.<"[/\+##$JK/T3P)6[P.;YQP)S^?@OS-$Q -M/]Q'^AGFN#A?KW]*^^@!X'9JOKW[7<[_^>;SOXOY*PSS$^WW8?YBUNYZI)>' -MUX]@?U.HOHG4__-MGO_/CZU_>/XOYNF8)V@\X6%%)3],SG]Q7OSU&YP7>WRZ -MLWT!X]1A_+[.!)77_T#[2AOC>^=9Y^_1>O[=#-C_\_0[3K[^0=\^\_0[5GEW -MUPKY[9PKXM$IYES<7UV/NK^:#'OAW%R9P]C!ZZ+\5.J_N=:Y,I;VW]QH^GV` -M^N*S_B?Z+CA*_\\UEZ_!$O^Y0K[<$?;C![WR,NX<%?9CQ6S8OW.$77$4-45( -MSV^%CC@W1]"1[A=5T"0XA_P/$2/+XW_P;<.<\+5S3MY_S='C$O@9/\/1'1$+ -M\)Z4_SGQ]:M[CG7\Q#^`!BES]/B8-P%CUVS];HWN1?]ONFB_/-O^^4-PMCX_ -MT?RW.$=HF"UH=;Q:/S^JF1VNYSG_(W[_:_R^!+^7/F;CM@UO_!$R.V*V=5Q@ -MV/J?;1X?D*F,H7?1GOQW);N0[&\AVZ+F3Q5HU#I+S]NE^*%JM)]D[:DY+LV1 -M5*BUDG^.]L999%_V;K%[/N"?9>[_+`4MQL["NW81?LU3D)-ALX2LT7OL&4II -MAH/U-8"7CEDB%H[O_6SO/@HX[_B8;HT8[U&,=]EG7[\'?=;ZR:\,#?@8_*=Z2>F1>*:_V6UR,3,5;T6_J&^L\ZU?RT)$WC^S:#*93_`SUZ -MN?3T$(([/5G3?,K0EOO-?^'[7ZFU_7$;?G=9J6Y_T#GY>;G_E^I[(ZW=WZ`] -MM]0H$]=#/'P+_!U02CSL3>^Q,!IZ&0V]A8*&[A&.'&54;WX7G37LMYPV;D8C -MMV=V@A?UEKV9+X7YCHQD\_58O==D3#YGQG+/GR" -MV[^O`=>Q,RWLWYFQ[.?'^>_W2OUO\?O.&>;[QU[PYL*,<2 -M@_V\'?2IFQ%N/Z>B?>6,^/K=.\,L?S>KV:5,.";L"H'O).`[<(9^SD&Y\J]" -M%R3-N+?Z9=S_F1[;/O6`-L'I5"=2#7A_3N]`9[2D**Y`IE*XVZ5HK\KSL,68 -MOV;ZO>5/<_RG1^=_9V'NG.EB#43FT/\R1<^A7^W#_C<].H?^",;IF!:=0^^5 -M]O^TZ!SZCT#GEFEZ#OV`B&_D^JV?9NT?^Z>9VX_O2_T_3=J/R=Q^_!CM.=/B -MVX\.B_'?P#@=4Y&STE^,?Q;M%Z?:L'^GFN?/T!Q[,%;M5%V/.2B6?;L^?\54 -MDJ'LH_R>S2_B=(^CSSO5W,[/53K?M99?JE5AX3\Z!X\RZK68_O]+L?I0QJZ5+)'.#U3., -M#E]C?F?,HW24QZ3I6Q);Z$1,0.)XX@ -M6%S*R.8494RSB\WU%.;J\U*T?6YW_VHML:AOS_!7E*'#SBI#/:D,KH2D]+!8 -M'9Z?P&BS5:[_$A'?)<_.-V']5:"=;"R2BW3POKB$X![Z8^K[2!G*Y2(#?;DE -M]OQK1XEY_`JOXYBHC6]*<__I_U)P\+35IB&8W=CV>?/E?-,_/DGE8NP%? -M_HOBO5&'HMRA=7*.KY.JJ'62U/E:?@\FCSV2YJI/*O1.??1[$G;MV];)UO8M -M\8;LM>F`L7&R7FN(]-]XM-=.QAT,LX.EO&T''RLF4\W=M@)Z5]U8+Y9RK08: -MSL.?[O\\U2@<)6H4ED;5*'SZ1I':U*-B5#]^3_8EV__;"RCV*>W"]_F2C=->0++WUX#Y9+'N%]&:S9'XA]JO -M<7_I68E_\;V_D\/W_V*#?]@M8J[387_E%%O[@5S^BXWO:XO?]\7ONR;%_WWK -M).OW@_QLC?J4HD"?I`RUC/U_:/(P-5GQW?H>\>&W$:]7.TG/*_P8=U4K)^FY -M(20K'Z!].FMO2BW7=B5EY8OQ:0^A\YOA*M4V:6/?7EF/^Y])='ZS2_/S./_- -MS%_);O'@W4LZR_IOC)DRZ?[HWSHQW#__$.HFQ,Z_24K3\V\NP/?T38C.OWE&ZK\)NEU/L/[5->O[ -M2HZ_!7Q3`%^'-S9\#QK@"P"^,]YH^$+\]X;G!S5=%7DIW9WA>4([\/U*KPW_ -MQVL._Q.`?QC@C\R]&9BFY]ZL!/R*5^;>Z/!_"MEJ?R&OZO?#A,^G5^_] -M?KC^A6CY(Q_2!SWJ?T'XD%3;G&*B/V*VT_!'GBCB,87L+^G0/R%>/_^%>_>? -M'#'F_R/.5U.[XI^OMHXW7[]'`->)\7J=25JKOT+[P?%Q_`<[_M]X:_]B->;* -M'*_[%WUS5(W[_^CKP^'(1AY@-J=I/?HZQYG[%QS_<>;Y7Q3OO`>Q'L?'Z?L^ -MV0,E&+]^'/D#(QL3;N3E*YV#\\E68OY!4-H'S^.[LG$RKTN\0=GKH3/;0/3,<\RCBJ!2[KQ_3F=1VHOQC] -M;6/-?868^F]L+/]`O$4O][L?8NR:L>'[72^T5[!V>J_>^+Z[K+/:R'`:C7/" -M?/'=*PD)+I?^YDD;?P]\(&QQ5Q3\,^NL[+O.,>;ZY4'P]L(8Q)^P/?9A_N9( -MUC&9ZR_/6T>`[HUCX,LPNXID\!OHJ-HQ/(8=ODP6E\%OT5?!^IR,)Y'GN^^" -M/F/'1)_ONC"?>TSX^6XV?C-@C+W[L_9M`+">*0JW;P^C_7@1ZAJQM4?O -MFUV2YQ]%@G:,7[=(3CN/BMRO,U+_%4F=V\'OILBV^=4Z^']%I!NS(_(HKH?5 -M6%B-<3*+]'?)/L;WZA;ENW&?;O887W5U^5X^^QSI_\SQ<1_^$)KVW*[_\P_PE/ -M^!W)WZ#]H,<:+N[_>>+9UT5D_P92>8V+A<>D3DG!'&Z/X$<5^T?S-_T_9^<> -M'%=]W?$K>6U60N#%"'OE8/GJ87MMR?;*ENT5EJV[DFRMC4.WE#*:%FR%>C)+ -MZM)M)TDW&1Z"$-@TB%E:,%O7IBM;V-L.TRP=A=&TF`CR$@V3;(A3=CK3=$L- -ME8GB+(PA2GBHYW?O]^P]J\?NBC\TDGZ?UYAWL>O=5L]83 -MU'B'N'^9Q0O>Y1A>JAN_H?%.Z]*VHC*OTAC3ZFLWY/O:*BZNH*Y(]/%@%9CZO,P]!G8;ZV# -M5+>K-W);-K^JM1Q0=?%S:`.,_7/7LM>@_]:\W\JC-VCZ6\I?'IL.\?FO_5:Y -M4NNW:939W#X^8U)S]J?MUA[_)R!_89^UEXSML?S\I>EG!#*I?2J]:\QV5*7W -M5^$>WUT_FO@Y\.]A?IO@/['>N?JK^Y5/@)^J'>N -M_A[>_SM+_T:XN\O4/]>S_PSV%(]?5<;/PZ_F'CN>U/S2KSG]>^;&;^:1^\Z=X_6/[L+X -M5?EX`GZFNPOK]E?@/M9=7OS&NA>.7Z7[X_`OU%UX3B@*]V`WUB:NJ@ZH\$_# -MW===YOZ?$N'?`_\F_87AA]A^/^YP7V:%_Q#;[R_S_(^_>/ZZG>WW%^:O(-OO -M%V_)4%_CS5MAO]]*4RM/66N/04K3%4AS=YGZY8SB\;.>\[]1&#\ZYW_#UF^: -M]*M&GHH;<_53\X?5T"]BE*=?T"@>?\N@A\\A4&WJM^!>TU78]O\C[__>>[YIC3;PUO"2:O5^'8UK]-97-/56 -M4KZO&N"^JNH'J'T7+3L&_._///#^(%^7]/\?2]!W$UL4?,+U`^ -M4FGX*-AS>W"6L6I3MSS+^`#X8WOF3V.S_=\S__Q*F,9ZJI]Q&'X$2"ZD;1Q1 -M[M:;+VWF7L7/@WOVS)UK,>L_X?_D:?M^.<\?(O]W%C]?DNZ<;W]&J[G?8!?; -MW[GP_HI8Y\+CZUU(RV.=]AO8:MYNN*:K,8M]>8]@?!?H5._Q;DQ0O_PC-1;. -M8!RY!79XP*V[&IKYS@7SG=MBY2NW>_[Y81=T2^^VZG\7]M_^#GNGQW:7M_\V -MMH#_TU@G#,-_-_Q_$_[WE^F_=W?I]QW^B_=_[%9Q9`Q7F?<%O]-SC?F&L<.P -MWR]N-<>[_![>=Z#+:S=1^GAI[%2U29V_OR+7=UZ"3/*F3S>^"=]4WOC@7H1C -MW,1U7(U9]]T/=P^Y5^?6]K)\&.ZNF^1]29?,=Z2_@;'CE0Y[[[;J$UVOY*C, -M_P_XA8[YQQ-?@=^C'?9XXD7T\Q(=<\<3]T'^X0ZUSV'V>,(:-QR#S$!'^?%H -MIG]'8?Y2^Y^4_5ZV'S:H?/#'R`U7!_3WOF._!=V`,4.LK/?^0VU4\_RE;KH$MW]O% -M^\"F"L[X_AQ\9)# -MW;%+Y9.[GS?G@LFO(>3'WET\UK3RX1L(HW77I]]_G=NY0AC]&?RZY$_7O#MU0;XI3_.3K8?-.']0IW'Y'=I;9_RNBWSGHURKT -MHWQFL([CT/%9Z.C8:=_/%X(>N1U*[P.)"E-7OZ'R5F6[038<2)6C7VK'_/7[ -M('2+[5#O^JE]2!M'K7ZR=1^7?">'ZX>C.PK7/(]`QT,[,+[)_V_8/+5]'Q#:;L6+VI?X%XBK -MV[;;>Q9OU/0I=;^:>H^[SES[*)P#NP-],7T[ZAOJCSO-]81?Y=<3SL#>C[99 -M\:!K+:;[*;A?)/<.^3[UK/74]Z[I:DRA7Z9C7CBUK3#>E2X=T.7);98N5=K` -M^PO=C?82QK.A;>JMH=:1:@I+U7$J_?^*TW^;6D.[>G3%K/ERI<&T91G"W83_!FNIK6W!^BL*@MB.A[A&E -M]FQ$W0UNA>L?46O<5EM?E8][;I\?VZ+F&;+?53*5],WTF3WF7>7J?U6?55%] -MECM3>`8J@G0+;K'/W&S5U=S7NQ-VCFSFNOU2?MQR"Y?_S59=>#N-)50=/PV_PN1^K>J[ -MH)X?_K@!_9>IOB3:N"^A[>C=S/>566]<&=3&+4$?XAC7?YO--N-9):?6BU5\ -MK./QWV9S#3I!XYDKV3.%=>.-D,FVGF_*G%&Z?'9(,_?P_RKOS_60>9%DTB3C -MG%4?YVV@-'52FD[,"F,)OK^WU4K3V>W3AXBK.UJM=D^R*V"&R>ZDVZ -MV@>=XG4^*WQ_8HEF3%DVJ/+J'RUVCYM1:O];2^G[P7^.M!QIL<_8I=&NQUH* -MY][^'>Z1EM+WIYOEOV7A\RG_A[F1UA8>EUACW`%J(P)HZUPM_/;[.^;=>HKY -MP:YL.M]4J6GFF]OF'2KF'7T'$B^'C8!*/Y=V8$3M*U7]8;D.JMZI'J_5>]5> -MW)+GOS<5GY]0[]A;[R8>--/K]%*_\8IF7*FI?-@R[M;NH'7NI3]_[] -MVSZT_QO/-WU#W3=+#&EEW;@X/7MNE^%=QSAA4CNZ*SP -M0L+>VKR]!\]6:<9EY5>4_%)^?!U^-),??R#'PR0S")E[(:.1S$&$H_R.4Q@+ -M^1_!MW^&;[_G.=^T>Y;_8<@#]S\XE_<3OPI<^YK%:P0/$M=PC^I>Z.4DO6IFQ2_GE8#(*^J;-GQS80/F -MATB&YTW_\_[M\8M[V7_&-;T-YZ\NN#0N?W[@[I\XX6^/A$=1AV?56.^76 -M6D9")ZRX5>^*J?WX3NWFTZJL>?/Q]:=F?+W5B_IOO?VF&NO[./2-,J/^^H>? -M'/E9GYE^+2/!$W;Z*>X1MCZ`;P^MY_:]Y>P4?>O+YZ^6D?X3=OXP9>A[7?`! -MP:UWXB[UN?/YJV4D,`]WY?,7<5$^F#O-,&[.I_&S;/^ZN?;?PO:OFWL?O=F7 -M$?;V0/:.=6K^IR7Q'[CLV]R[7$14>[1NU,;VOW\M[`0ZOZ`DO,,[Y-U.XTF>W.Q@J_4>WXWS[- -M<;%OW8Z$,7R#[G^P-M'[[DS7E0I-?W]CQ9"?^I>_G9GI:JB@N'ZU4]\G]P9\ -M!F%_U+2(\5_3_/-/_=JF$17.\-*-QJO4%O+Y)15.!<)YLDF]GZ7NM7TG?U_\ -M>[?`_J8RY[^:BK3_&(.W-A7V,9Y'^M4V66MDZNT8'X7]MSS_VUC^^>YT8_'S -MRS^`#LE&KC=N-MOC6W]MW9^@]!F"/@\WFO.\^;V32J=[H%/(U*GEVXN]?\G; -M./_[5?GW?[#/Q]EHWR_[%>ASI<'NKQV%6[:!U[-G^OJI'7_F2UC_:RA\BS`* -M^51#B?N/&HK?S[`?^H4:Q/V_\/NV!NM<646[UJWJIZPZ'P%]?`UEWO_2L'#Z -MR??CFZ%'5K?UV`H]7B.WJTD/CJLZN(_JA6O>37`_J5MZGZ[Z9<_P#8:?S^,O -MUXR+RA:U[L1CF+AZ7^>+F/_4"^.8PS^DJW*4_:YBO)_9`^;5%ZX#3?OUXO'_ -M-O+OY%K;[G<1%Q?([3HS_O7NI;A[<)KR?!W6'$?7EG'_\=KB]_=S^0FMM>XJ -M_\)!K/^M+8R+*>ADK%WD^9<2X9]E^^O/-XVI^W40?J9>W+V,NV]_!!U>K"__ -M?I!8?8GW/]G^>E7N9OH\%`>O'D#^K[?C0*V1G4'XG8L(WU5?XOU/MG^-?7?Q -MW9S^Y$8=`X-_@BLU(T[ZO0S]1M>4D?YK"LO?G/N_V?XUHOPC_-O66.7HNMI7 -M>I2\*BLK4%9\:ZRSD,LT;:JR_94>'I\]0>UD)?H9G'[F_G\^_R=T+NO\_XVD -MPX>V_AE'_0LR_E9R_4]R&D8!68=81+H07(_>LHWXT45G?2/SL=,61QACE -MLX2!^0_SN\/T7:,:JP\YM<\-N;0'A]S:\%#<-VOTOYXW6W$PCM<=DP]E$Y=Y&UN4^Z'+Q -M,[8N%/80A3U$80]1V.9<"(5[BL(]1>&:NE#80Q3V$(4]E)Y')J!5YOL$'R&> -M!BF,9J2/BB^/UO!LEL+T:OY1I9=;N^M<39X?)F[:/$(RHVHN%6ZC6?K62[^M -M;SYW3H,-.FQ0WZF^R>69KHO)RL-#*BPGZ:?2A\]\O`&=IE;;>2+GF-7_6;WP -M_5GG\/USJZUZDNK(MU4=J?HY8X>0_JM+W'^P>N'W4548CR.,P&JK759G"U[F -M\Y^K[?,DO";Z-Y!WKU;S'FK=OCIO[]^#?53'[4FU>4^E8D^"9>L6>?]S79'[ -MO^#G8W6X"TG=;P[=(W7V>[TJ_"]"=J!N!GFDWWV]5G5^7[,!WHV[>ZV[9T`/WDVYKK,WG4-4WK9S_ -M\0W'^TZN_]RE]Y/.:[_;CG\-YWOKD/=JW:77+W*KYD\_M3]Y)H#^SZK"_;-C -M%$82++5J_GV8*?#8JA+Y?]7"[Y_G[__'/HE>DAT?W),_`_%#]$-:S3"J4I]F -M_22WNZ&G/#UGI?,^K1\9766O0DC4=])^ZD,?!,7X3L'4$Z)HA; -MZX85YIFD+,EYA=P)R$7@3X:X1W`NO_W@:>*ZX'\-[@.?(.X6_"$N_^#CQ%W$ -M*[0'&A7_*OCT#18?(^X4W_\E>`8\15P3_`O@8^!)XM-_9_.[P./@">(YP?^( -M[0>/$Y\4_%:V'SQ&/$M\"?0_R/:#1XEGQ/?=;#]QKTB'09)+"SD?Y'*UEC\1 -MXA.">\'3X&'BXX)[>/T7/$1\3.C)Z\,Q\`'B*?&]&SP,WD\\*;@+/`@>))X0 -MW`GN!0\0CPNN@;O`#>(QP:=Y_^/U%O<1CPJ>`T^#>XD/"CX)G@+W$(\(G@6/ -M@>O$PX)GP,/@;N(AP=/@07`7\0'!)\"]X$[B_8*/@[O`->)!P(&X(GV7[P2>(^P1-L/[B:P_2*_!%G^\&S]+U'?!]C^\$SQ'7! -MHVP_>)JX6_!!MA]\@KA+\`C;?QWJ">).P<-L/_@8<4WP$-L/GB(^';?Y`-L/ -MGB2>$[R?[0=/$)\4/,CV@\>)9P4/L/W@,>(9P0VV'SQ*/"VXC^UW80\C\0G! -MO6P_>(3XN."\?S@%'B8^)KC.]H.'B*<$=[/]X`/$DX*[V'[P?N*)N)U_G&P_ -M>)!X7'ROL?W@`>(QP:?1IN:6HWX@'A4\!YX&]Q$?%'P2/`7N)1X1/`L>`_<0 -M#PN>`0^#Z\1#@J?!@^!NX@."3X![P5W$^P4?!W>!.XD'!1]C^Z]%_:#*O^`I -MMA])>T3ZQMA^<+4NH`L>9?O! -ML_2]6_@_R/:#9XB[!(^P_=>@_B#N%/Z'V7[P">*:^#[$]H./$Y]^6I1_MA]\ -MC'A.\'ZV'SQ%?%+P(-L/GB2>?=K6+\#V@R>(9\3W!ML/'B>>%MS']M>@_B`^ -M(;B7[0>/$A\7W,/V@P\2'Q-<9_O!(\13@KO9?O`P\23Q2MCG8OO!0\03PGXG -MVP^NUD?BPG^-[0(!X1/`L -M>`S<(!Y^VNZ'9L##X#[B(6%?FN]_`/<2'Q#Z3X![P3W$^P4?!W>!Z\2#@H^Q -M_=6H7X@'!$^Q_>`NXH;@2;8?W*G*O^`)MA]<4^5?<+[?(@P^_0R5?\%C;#]X -MCK@N>)3M!Y\D[A;Q-\CV@V>)N\3W$;:_"O4#<:?@8;8?/$U<$SS$]H-/$)\^ -M;H<_P/:#CQ//"=[/]H./$9\\+LH_VP^>(IX5/,#V@R>)9X[;^Q_;[T3]0'Q"<"_;#QXC/BZXA^T'CQ(?$UQG^\$'B:<$=[/]X!'B2<%=;#]X -MF'A"Q)^3[0+_XGO?7.L%UXD'Q_0ML_S+4`\0#@O\SVP_N(FX(_\^R_>!.XC[!GV'[P37B -M7L&/L_W@TZ>H'A#A/\[V@^>(ZX(_PO:#3Q)W"WX_VP^>)>X2X7^9[5^*>H"X -M4WQ_#]L/GB:N"?YYMA]\@OCT4S8_S/:#CQ//"7X[VP\^1GSR*;LT'CQ&?$'P]VP\>)3XN -M>#W;#SY(?$SPE6P_>(1X2O!KV7[P,/&DX,O8?O`0\83@GV#OI!-\@'A<\`_` -M)Y>@_!./"7X9?()X\-0:)W=#N6N6>PW< -M!\G=1^Y:A>6^#.XA`_Z/W:?>>JH-LH -MR4R?M&74]Z_C^SBQW$E+O[8/&@XJ]B.P>XE-"B;]YOT1_223)9E!Z/4BW`UR -MSPCW%^#NJ43Y/$GUMTB_^SG]P2>(#PK^94[_BO--XR?M^$S`WS2YCPGW$W`? -MJT!Y)/\B3]GU^5WP+TX\>\9N=Y(D%Q9R_9`+5UCW2[-<@N2,$W;]=`OD`@@O -M3CPD_-D/[B$^*<*+D=R`D.N$G$9R3A%>E.3ZA=PVR&4T2EOAWR#)!86GIZ>F19GKTO<`& -M72O0N22Z?*+K!+H1B2Z,[93H9A.=&^@&)3H?T)5+=!:B*P5)Y7U"Y:F$YP%NE?"/">>$6P'/D?#? -M$,X(SP&<2?@`X6>^HWD:\/&]"?Q]PD\1/KX/YC$)[S7.OQ`^`OBPA.\GO)WP -M8<#/2/A>PMV$GP'\M(3O,MI/^&G`AR3\=:/]@`_M2\C[@Q]3_T/ZH)1^E-)' -M[L"XWY?0BT.4?OH.S<=0SZ!4S\^IGI.$]P-^2L+K">\B_"C@)R7\;PEO);P; -M\'X)?X[P]81W`7Y4PI\FO!SP/5)[8L0WA_3.?0F]"AKMI_+:H;QNJ;PGJ+SA -MVS3_`MXEX:6$#Q(>!GR/A#]&^%'"?8!W[DWX'_F$=Q+N!KQ=RC^7#%$G[<:/\W-*[?!OZDW[L^,-I/^`C@7,I_V&@_ -MX<.`Y^U-V.N#1OL![Y1_%P0ZJT2WE^C<0-V/\,=#Z);@CH -M1G8FZ-J)S@ITQ1+=(-#YI/):C/;?TN/:&G2G@*Y+H@L8OW_>TN/'&G0G@>[4 -MWTGSO^'_W=+O43;H^H$N1VKO>J(+`UV>1'<4Z#H[$W3&_A77+?W>W[B?`'3K -M.Q)T-43';^GWMQIT74#'=B3H*HAN?%R_)S7N+R"=U*\.HAL"NE/2?-P)=.ZW -M$^4]9O3_.-D7U!]);OE&_Q/>"OCXKZ3Q;^@_X>.O;SOR)J4]/R[.KMS&WZ+/ -M/5A9$'Y;_RVZHY;V?XRGVW^5^!/[O\8SQ+\W?57;C^LOVC5M&]:^[B7O'V3E,!]K#R%LG80[BS<$V#@`VL.0%MS.; -MJ;<6FR]5VY7+U4N4+ZLQ7SE;?1C/YV+%AW?3/A]8QCS_K-: -MO+=@IND]9T_V>\Y:OJI&G*N*I]6ORSV7\CK[G6-];\@#U[?-?)V)#F_&\$MO8 -M:Q+[V[R]J7V13O^R<(\OR"O+?+8VV_QY;7:96S5!GIXY[2J>Z]++.%<[Z?FW -MTW]JR,_H'C7.N>C[WE93>N?H#]O?4S?%^@L-_R>E_GS#__F! -M]0_=2&\_^]H?G7J.UWKKK -M=]LIPR8I9*^F8IO2[G_Z:O+S,2CK&:!G3-P9/5'[R[D%+MRWCOS]#?'W_E>) -M<6J?5^4JF%>/]\WUVEJX"_,\8'+6&'F>ICRM4I[%+:K+8EJW!O.!;'H[H([4 -M?,;Z797R+:6Z5Q84X-Y.0S[K1Q(QP49Z'SUC[*TV,G7?MW'9DW3.T_AW1SV@Y.K8= -MF4=IEZ\)VH$ZB5XE;.B:;D^0?@:E_>::B/$P,-2QJM:>QCWBSYF?/^CURG2;)16=BT1\_JO*(U?^W[[ -M1T>N)MV?=SR/O1S?2_S'JU.(_W!ULOA)NGW&&-D#5&;[5=U6S1`QLB_),;)M -MN67M%`_[RW@L\`\HGKD+\B&]F+>E.QT96V>O8NM<'F4=W6]H7\E,ZYSL>:9. -MY7SDR)7)XU_/);X'KR1\#`5X-.+0&/>\O$)]WWU%[_M4_S!C_U^Y=_R8,+/W -MNME]AWTLT#<3\NIW:'XI[M`LK:;UWQ5=KEGB#)U^%N!U$;/:[9P'O+X[YW6U -M8'F'BO=.F5@E[\DN4#^:[:ZQ@I]G8J]QY&=F6;<3XSPJH@RGO6J6$\JH%65@ -M>P]!&38H0QFIK.G)]HA[-*]/5([F@@^%-&:)INP# -MF663_OQ=W>4,_3-[0=6_P)QB]`E3-G'LEY[I!4*?T%>78[NA+CU"NG3[2]0E -M?])=9?IX7:!^G_-G8;!_;E;7:Q)W__3W]IC?4&>)N.'M:C;4;_2#$9]`^%Y` -M@[+,!AKY;&./>3G&'Q^=#OZ8<7[#!#19@DZ^Y_0-5=QS:GXY?L_I-*:>.W3, -MHZ>_X$FZ__0Q\T[5J%,NRZCS8Q'/W(%W!T'_.*!_SD/_7*@USD\-7;K;/M49 -M]W_06:'W+^&=M[D#Z>)/[KF4>?V%Y113G,M>*LLMREI[;"KG$Z/LOIN<_IV\#WAW\]^?TK>K%V#EXYL7! -MUAXH9Q=/A.'E@Y<;7N-`B_>*P'O_>GC^0?N_A]/?O^TBWEXDW@:'<0U:R57! -MS_>(?P/YQ+D0Z`]SROEG??[,?#^C&/_#]_8?#!\AIB1\A%:2LW48UUDE(H85 -MTC0#S1#1A(CF\H7$O3_H.UF9/SX'#EV8_'QA_P59?M;#T\!_&,?XZE7T_3_@ -MB?N,[X[O$P8\G-*^[-F?5'/VZH`5Y%W,5O?C>0`?6WT\S#8>;V6O'F]G!X]W -ML@^/@Z]\4&4;#[K8JP?KV,&#Z]F'!XMAC5@PYG099]4?!)OS$-@B'_"TD,Z. -MWCZ??$[]B/#5+8=OPUR&O)<0[W\\CVW/K#\8+R0;VIO#'.*L.G/H,4&,]LEX -MQQ,%=^&B_>?3V!?HF]-M]/OG>?V[%[U,MCB9!\N0_R_+X"_/HQ5HU1-3%CMZBRKN(M"UX\%/`OFUI[I -M81'CJ,><796#<98=#.:'!O40I/?,<!YA31'"::P7/X7=PI,B2S7RY^A/3 -M9VMFL/:O'>+^1=U?JU?6DJS7BONE5Z38@WFP7LR&-2'&T[=-YR[%C-]'5:K% -MK/V+\=[?]BK,6Z.8BC"N+_0MSMOIR]TQS>T:G7AM].&4\BWPCFO.V:*\`W0. -M'7W-*V*]]#E]5_"GS_7UDF*R0UT=]H]91[PNK_*FRV3J@+K>%'7-@+%U!?H- -MYO@OED[25MEGQ=A,51/)=XFE?N\$?1K_[FG2\T^?3RU^59)N2/J0GY70AR74 -MEW\ZFZP/"[(2^E!`-"?/)O2!9R7TX6'"N\[BF?')^__[]L\OJ']6GM7[9X98 -M\]^[CZZDW`./\C_[W>3R5ZE,::%?&>GPIQJ%=![E(5TW\K"E?@=79;(D_#3+F)\BS1Z@+8"ZJZ2_4.\ -M]T;V_PN9>OY1DG,V>PU\5*O8IWO*>6_0"4G5J^;;E: -M]2"L!P[-86#+U*HDGQ1LF_!)Y[3';=RGT!=)]O],9O_0F-=_#OK53_JUG=99 -MY9"OQ[P8[?^H`GV,WVW($_?]S.OG`&O"-#7T> -M8YVL_]@>-G2LBXT<&P'+]+V;._3NG?OUX9VN]61O;[%.N!L.(XT&.R_:PXR['?D35RHAQ> -ML$`]X8)7';S6P\L-+Q^\PO!JA5<[O(PY4M@_G;\CP%\?\-<'_/4!?WW`7Q_P -MUP?\]0%O1X"/7<#'+N!C%_"Q"_C8!7SL`CYV`Q^[@8=='<`+`[W#LG6;NGH@ -MAVT$/^S5@3QV<*"8Y9]PL-4G'L&S[W/SGYD_=_4S=L8OO)L]O]K&W*/OFN=7 -M_T^9N^:TZ;6:1^%98>_P+*"UW=SARF8V_&UE%&.I=3S!7>_>JE:_@3EJ.L;$ -M`#J=1@%_R3V*O[L@S;>@@S^:7O",P*=O=V$])I.G=I_)6U,(=77!.]+]XQ,< -M:-@%7#\^8AH'W<*SWAO!MWZU%_B&-43^$>#[B&[3;F[Y;F)!P7O0OWG`VXV) -MB=^G:RMG'R:UUVR:7_O&V!%7#NL^8\[1/V\?F_Y,-E//E)O'J[>/+0(>U#,_ -M,M^J+IV23':FD4EMBDQV_D5D4CCSV^I]6;TUJ7*!-F:4S760"_YV\H@<#YYFP0=G"CN\`&[-#MS%FIWIU8M,YV:YB.IXK -MQM_;5CRN5@$^%OJLPN]IG@1;GF3_6;6]BE7C_/&T/']@.>-0SK*4 -M^549J7S*#/X4WIUH&^MQ%$?,%';7S&3MY_`[HD)SH;K"7%,U -M37S_+=?W^Z3Y"GWF\8EW1E]_47TZF;]W^[/WZOAMP$UA]2D+E'TO_HWR)K-- -MAGUR_'=B_:"`O!X"7O/Z8_ -M"RN*VOES6HL_Z@\%>5'4PHHQI2A:8F$_UII"D;8*7A3P\BT65A\*Q1K]`8TU -M-$+[ZO6_OLFI^R%65L&9*PB(9O/.;3>+0M&M.:*`7K:X]D<7Q_ -M3J3X@YM+2TLM],0;/5"ZU\9\GD!2=GPF?KLH?]07VLI]FB?,FZ.>S1K#CYC> -M3[B`ZCU1C7MBO"ALY[%0V/C8'-6\V"8+T&W68MSKCV[A]8%0PQ;>X&G`:F.> -M6)35BP?\#'36J%YND:.\E1'@I'.8?W^K:P)QK5]`>?/Z9_ -M:/)CFD7POT6+!+7`D_I;:2C@%5+E'HZ"Y:$(1YD">SH!,\3&'%1_@R>X*,9% -MGD5%T45V(N1-(6\S%.`)1#2/MXU*(6I\$-06%@R)O)YZH)6JX)[F6*C)$_,W -M>`*!-NYIC&D1X,FK!3QM#+$X'R[BHQZ*%+`HF,5"(=[D"4+6R.;F)BT(XC.R -M;=)+>?:O&2J7RQ_C+ZT)0OD;H$OTAOB;FC2OWQ/3`FUV%`&6$X+NCP"+;;P1 -M4AI"35"ZEX/%J,:&DH'N!,!/_ -MQ)^/Y"**YF)8B<&P3/1$I%10&N/E12U2'P+5Q$0>1/&W0*'8*4(Y^:+*12B< -M@#\:,YH.HA.*SOU1ODCD6PD:[6]8S5]:&6VNUS]O8/Z@5VO%7A8D\6*%$$5' -M)97)*ED[\>V,DQI@A04:4[1T^>.HQ%"]&'$MGH@?J8JC)2*!=5'^5:)W#5C4 -M)5K6"#+ULJB&*FZ@^&C(LY_R;XV$H*N"S4WUT.VA1DF/FH,IN46"D7^0\FL- -MOA"^GZ'G(,.!P-@X/8O4V@-C&L250KQB$#LZ?IY5MC -M>O[%BQ?SI]:N6P.BX%5K:M<^RR'%DI2\YMD:/5&+1$#<6#:J'^B.$#J,+!@Q -M+?X*BJ`;B]T4JOP7DQU4P3Z@Y%;RX.;@E&-H:++%0.X'):`@XJ];?*T27 -M0#]'FQM\G$`:XW)7BG2]*[F116>O28L*PTD5&=W.DK0VTD#/^*\4BFM$@_=\ -M6UC74=0JCZZF(#M#<>RZ@NHP2I(G#1HP]_HP9H6_\*,A"$>TV#86_\A"6X0( -MD-NP)P+#03!L$1T:KX3C.#6ZRQ]L"#1[18^I,=E.AL):4$A%+TY_`<-!#2Q& -M!4\J?K60<_O\.Q/=^7_0]/[76OIR/J2\LS%.*HY+F)/U!G].8!SYO0H74GRNX-*O1 -MM%>O-:*>Z;DM4\FQU1_S&7-G3.BS&#MWY222Y'DU#9VPX@9U<9.GK5YW(_P- -MO-X?]$3:*F$HZW#0TZ2A&@IO!$=F3&N-K7*T%@5:.?-Z8A[C)O0EP>*)ZK%! -MX%,T^B-@V,)`96'INXAZ`.=[HU2M56N(\Q/5-'";4S!/I,$7W5J*4L!*A&&4 -MB(@M*B&`1127H#<`_DT,772=T>A=.81Y3"&BXE$Y0#/8$B:KSUU5AIK!SS?X -M%M:;E(HOY=$M_G`8??/,N70&[LZ!RJA/@6BL$5/MLB?%7/?D,EV%HL)G2RBDF-'$0,)T -MH#])[8!Y%5N'6L:C8:W!W^@'N8//X0^V>`)^KSYB<'BPK9Y($!R#"D-+!>LI -MCGMS4*\W8'CV44HR_)XA0WXH5UHSQ%F.PB>B&X[[%V!L4`1<+.^$!I3H;@&X -M6B`0DAEBA)YH'01G`[]=Y(,^V2.Z3K^^9$\MV&)`YY0PBA -M7\+104-7.(5,B!^+BV@O-_LC6A)H8?K#)M02]K_$/0EX'-5Y3[9E&]GF/DQ, -MX$E">&5Y5[NR,2#+*]FRC0WR*5_XWMV9E1;MQ -M29/T"DW;I$E-"21I("5)`VW3`$EZD#84IR'0I!';_WHSNV.+(76_K_OYS3__ -M_[_[O?]XQUA+88I$1@K2'\5$/I.BUN)2!ZT,SG.?$\1%:-6MDY5,%A81W3H. -MLMJGYVMG%-:5B#3K%#0)=,U";_VBK8+MQ$E=V1`[D]8Q72PXY2*H9+!TX.`D -MLD"'4HH9]/5=7GFX!.VT0=IUE(OHTZ@M*F7#@^507B\%FV`J!-VTNF3;*P97 -M[CL`D@Y"K]AI<]$:SVTQ](/G8*TOZ%%87=G4L7;B`+XT@]^8+)3*(+!-:J/G -M%S6SU^0F!A5ICV7`_08O[6"FJ")#!R$"/@^F]^&X=^L:T6ORJ'EWE=ND8I%8 -M9)''`C6=A1Y;F\^@$BE78&99N*)CIPVBX=SIQK19XZRYQ$K>'@-Q@WKK51M6 -M8T4I+TZ:LJY:LB2J^E=&HS%6*[7N+C3'H4V/G%T>!H$QD@I>NP4][F0.DF=9 -M*)4@?V,?4L-V:D3E;1LU%NE:,$DUT=`X2"3ZW7-XHMIS9*)ZT@S!PRT3U$0AO0!BX=:+Z8PCJ-O21JN0GG0GA+`AGR_R="6$&A--H -M;QZ5IU*-$&9!F`9A-H2I$.9`F`+A=-I#4NH,"*:!O-5!NLB0G'(!A8@YH,:& -MRL..MZAG`BH_"]1-(I^RC9[W\H2QDV@ENV@GS`)MX5T3U6?OAO9^$-I][T1U -MY7T3U5_>#^\/3E3G/C11_02$XQ">>[ISSO>AECHGD2DWQ#4H@+)6^G_YD\VK.6W.G),O&A1,.WL(!+=0)-,*56M+ -M-2G!1/^`-Y=WUZPF"DV+'"BA#"[&C%@F*^DT2A%.9(CA`)I)93!9CK;;R+\0 -MME.&69X3A-0OO[H,6+#YYR(+EQ$J3:CN+Q3'2YFAX;*.7775Y6%X7*G7)4HC -M>KF5A,T2?3!;VH*A@-.PDG12 -MI4P2Y\TX>"SD6AOQ=31,+5NF;M9&HS99'%]>8N`Z10WXLSD9VU\;HUU.J$(= -MP\X5R^/U-%Z$&,55H^M\I:8*EJ?TW!R(RC_]-.BF9V!]_!704Q#TUT!'0=CX -M=5B_/SM17?,PAL^'F>A[L#H?:K/9))N([ -M3=TTS/5N/51)E*P8^5BT9UA+[O+(N@.\*+4<+`.X>,NY8Z""N!*R.MO(.8-T -MH;;B0JA,-X@0+.2*!7+U?"ST;BI%LE"XX(B],[M+T5%(&:PB6$:[=`"Z0;LD -M,T(6'IRD2XDAVN;%#I$(AF9;L$`)I7,H"]DLOA.4]<_K$]4SWP8_Z3C#VK`? -M:*\(_SC`8_)^#.C/OXO@SV^R$'WCW.MU_X18#/0XB^ -M5<.3]WM^[M&.PSL8LJG3&J?/F'F:G`_.FCWG]#/./.OLQB^^1#>WM%[:=ME\^5ZF?4''PG"D,QICO&O1XLN77''E5=U+&>]9%N_M -M6[ZB?^4JQE=?O6;M-=<.K%N_@?&-FS8/;MFZ;?N.ZQC?N6OWGKW[]B>2*:]F -M6!NNARD[U!Z-F9(X=\S7RPO36W9Z:#A3O*'DE"L'1L?&#Q^Y^>@MM]YV^_OO -MN.?>^^Y_X,,?^>B##WFYN`FN'\GF\@4OV4'R-%&AXPZRUH.;UVFKA!(&*[(F -ME;3V@8Z%Z3TTWJW7=FX@;P9]2N[R[^W(LWOS2OGX["^)@`-P1I -MT4U'HO+[QB]>>_OU+WWFI6WK!O7&Y0,@4`>ZS=)\P^#J26FH+=Q-A5(ECSL. -MD.O&+2LV@_;O]OQ?23<(!A3T&JP(ZW(`99<"_]*V(.TRI?"8#$\NV+19N!S, -MH2^.=%'$4O///O#"9:_.BIQECHI#H`KNB?0!\PQ8`",=A;36BG$*Z#$K=AO28URHPF"'H -MUX4:&=NA`DX[)MBV;M^JS9M7[5B[A:N("Y]*'LPJ+(!=MT5\#K"HNJ7-:5'; -M>?L+XVX](>XHY-VM)VL2F)=**$MC:84%@LDCO]O.NC$9OIEFU118X-0>8Q0&3,4AY&*J^$3:]'_>U3$-QTPLR$@<).U9OX[6I[HI$ -M%\F,`16Z=OW:+6LWK!\4ER6LV?&NG89XE!OF"6ES[K0A.4J;PLE:+Y!3Q4VT -MDV05%\P.%`6HBC0">J6D:9\`)1%/;>L;B:Y&5B*@MC.;<#2\H;;6[%A[/1VJ -M74-V6BAF"R&9M.[4H\,X1T))FD.@>2D)1Z[`%,B>G$4[>R?E\&;)R7F]5D&' -M>(,ND72T5ZW)Z%D8\?JL6DU>'>_`PR;RB]?ZI:J;Z;2EJ7BOTSO?7U8;EP;! -M9=4P4(^#8UNNCPY+%/"-P6(J=^-464588;>JUKAJ==1\%5(+U().^(<;V1VJ -MHUE1_=5"%<9]O%85:5&=BKC1'A5=IJ)Q%>M0L;#J:E9="U17I^KJ4UT6K(?@ -M68$'3B#5A5NK8')Z5$\KF+.XBB<+UKB*9_(J+LNH>$GU8H(^E<#M4)4`^U<$ -MD,T,Y?D)SBRZL$`#O8`WC%32'H(<4LTJM5"E^A3*:P<]'94:3I3HT4%/Q^T2 -M>*G@$]<>J4P.Q-F")7.4<>09A^VQ]0PWC+*J$P:5Q8VM.EZ-:)H^BB9]HHZ-^L,9])EE5N@ -ME/E@)@JF'^LKN7PGO@7&& -M(#Y.'`P^]J"3ZRS!"M$I5$H@D;11KFA0<'];T99D):(J/:H"U:AP0_#@`ZI' -MXN7.0$6"J%!-JC&HURZU:_X>M0L[>8_:HR(AU9TOT)D?2!'?(U#%3&I$X4(: -M*DG=52XH[$M;[59I7)RJ="I;<&B5!:OC-)VWI$?L<26A5^4,'`5>7LIN -M5JBDPIE%5R[AMT2V.)Q0G32ZMA4&VP>V3G72&'06(;^$9:'I".,B/YS,E'%* -MP$#A(VR/E;%4W(K%,0C3[,$71O/TK/`3U]ZX51XFKR3,TZWV/86F5='I`"^46$AM/;M*@1=3"]680`5I@KUD>($3IDI[884]6A1EQCSB/@J:0DX -M`JBX5B&9)2"M6Z$=M-7.]BA,O#J$DHIQ,&8$I`7F.NVA.#!VI?)P&*<"&A^\ -MTA=&MQ.W%8:,>9*$7BRG)I9KQ,@:UL:A-'49$$)5,M$<%7%4D!Y$)'G -M)6V@9^5)*2(@QRJ"$A2F:=CE:H,X35741J!K<<^8I@0Y)+2]HBP103MO@2!S -M2>'1C,53FZJL'"/.0`]CFYQ*$PE`<`70P]/SSD!%.8)J6M=>ZXNB2DN],5Y1" -M5K&=W.5)O+T#.73UP$'S2JCQ\<-Q/)/?4`$UD[`R8Y!13-YZ]*(KE`A>JJCP -M0F:)-F;0_73/A&D'!RD+O3LH\/O>YU_[=.V^[#-7\_GI$P)?F:H(-JYA_&=" -MQS^N2^M?H<\5>%CHZD[&S>_!"N,[*O7T-;YX.WSXC9+O?H&OS.;\GQ>\*O`' -MAC^'^4?7RKU-@>I,59?OH]Z]EO&-`I5F^L."WRGPF-"_(_@S -M)GX+T\\98'R*P,-"#PW4MP^<`,*[?71]*=,/"'VOX5_&]!<$?UK@8_.9WK:> -M\5D"U6*F_V@#XV\*[-[$<)7`WG2JU^I-]NK>;*_3.ZJ^//M)+M"FPW]*_%0DV[.JF@D -MIM;!S%Z7*.FNJ.Z*=4>O[+Y\B;YZW1;`HU%U_MW&Y>R_@^$K`M6C`C\@\"Z&EQ!)J64[I)YW2[K[&1[[F,1_F*$6^)C` -M:I7/-8]?Q^G;=S(TYQ\W[ZSOQY9=C%\@\'R!LP2^+?%_*O!E@=\2^,6=]>E. -MDW.4_3.DP)DPM^5@%<]:M\SD\ZK-,[BM2"\*C$H&QU`>9O`Y"]+W"S0%/&8. -M:@4>%M@G_%<"V#J3S^>P_`ZAEP4NEO1?E?+G"-T2>*GP/R&X -MR?\6@2N%_ZJ4;^JW6^!%PG\0QV$&GQ\B_9#`'N'_G8S/!4+/"EPH_#\3?+;` -MNP0."/^_I/RI0M\L\&QI_^/2_E:AEP1V2?HO2_MG"3TIL$7XOR7X%($W"UPA -M_'^2\F<(?:?`]PC_`6E_O]`/"NP6_M]*^\\1^O4"%PC_"<'-_+Q3X#7"?T/* -M;Q3Z-H'GH_S*O,7V+Q+Z`8%+)/VSTOXSA)X6>)GP/RVXF=^W"5PM_!]+^:<) -M?:_`BX7_B+0_)?1?$Q@7_C]*^^<)/2\P(OR_$/QT@1\4N%[XO_3)_R;AGR7C -M?]0G_S<(C$GZO_+)?T)@L_!_4_`&@4<$+A?^#WSR?YW`"X5_GT_^QP5>)?QO -M^>0_([!=^'\LN.G?.P2N%?Y_^N1_J\#SD#Z3S^9KY;\B\'))_]<^^;<%M@G_ -M]P0W\^M6@:N$_V\^^=\C\+W"_YA/_F\2N$SX_^"3_YS`L/`_+[BIW]T"UPG_ -M%S[Y-^6<(^/_E$_^'8&+)/TS/ODW\[15^+\CN,G_J,!^X?^+3_YW"9PG_(_X -MY/]&@4N%_X)/_D<$=@C_(GP'_7)__L$]@K_)9_\%P1V"O]+@IOZ?4C@ -M!N&_?8KV_\D`^_\;`?;_^P'V_]X`^__-`/O_1P'V_R>G:/^_%F#_/QE@_W\4 -M8/\?"K#_?Q]@__\\P/[__!3M_],!]O^W`^S_/P?8_P\'V/_O!-C_/PFP_S\[ -M1?O_7(#]_TR`_7\MP/[_>H#]_UZ`_?]B@/V?.$7[_U2`_7\\P/[_,,#^WQ]@ -M_[\=8/\_&V#_?WJ*]O_K`?;_4P'V_]\#[/_#`?;_NP'V_PL!]O^_3]'^?R7` -M_O]N@/W_UP#[_]$`^_]B@/W_TP#[_]8IVO^_";#_?Q!@_U\/L/\?#[#_+P?8 -M_[\,L/^X`;&QD>5S>R/?X1QL9'G:U0[G)@> -MQW='(]_]W-+(\K^[D>]Z;F[D]NULY+N@VQI9#QQKY/N?F'Z*E']$RK_0E#^7 -MRY]ARI_.Y2=,^9)^FBE_*I6;WY/[O?T7_'U2\"F" -M?TAP9[U<$ -M/U_P%P6?*_A3@L\3_`G!+Q;\XX*'!;]=\![!'<%7"[Y'\#6"7ROX!E-_P;<+ -M?K[@.TR'"B[7E]3QO8SO%/QEP7<)_DW!=PO^!<'W"/XIP?>:?=J]OOW22>Y+ -M3Y7[P6?(GAW*#LH1SOTJ1*A"A"I$J$*$*D2H0H3J^_BK@RK].M7_^P]J@1>M -M:N?GX98&;G](X*4,]\]G>&RY[*.V-M3UT['ULL\99OJ$S?%>M7W]>:WD)_`Q -M@7T##/6ZAKI]S'?[HS5`]$2Z>VR>WXJGZ#HJ+\VZJ9MO-S3AR3P3K0I^&$34 -M&'\FU-&LEV),ODZA=4B/Y2.1L1C>KFG7=*0,6>)%`CQ5Y@L"E`#/",.4``\D -M,3K!=JUW0=Y\Y62/>RT"8E*J<*E0YD0ZJ5.8*D6OD*Q+TYD6Q\-K"509C#(& -M;&H$5C_:@_U"+\`0,/Q;DDXCO( -MSYL8W%Y.Z#68CO-;N"+N=U=0>CTAXH^1D@$(=_D8IFOJJ?RQ5CV-6]FTM.8[ -ML::H]AJ:3N#MD*9PS".52Q4;*]T3AXR6Z>@R;D,4\:B'NQ^2Z84R#4KX/YZX -MHUIQ.RW*7T]1I'RF2/T8TN/>`-%M%YQ1-$\H7KF2&O'%@Y=VB8<7`3B>?"X+ -M\GM;O/A4 -MIU2?1^#;`U@V\V)AO.)-;+[VX\:4(VXFR!4>NFU"71WU^'6#+JTU;97!,>WA -MUIB42W5]2IA$8>XK3Q9J2_+'[Y4A-M(-T?MTA/OO0%*:* -M=7C$C+Y"XR>25\"\A&F=*IGY[5Y`HGYHXJDA1^2>`%.TF*X[9Y=:%<('H"W) -M2A9O1M8GX.\JH07F%AF582Z,47)?6J^#>?Q,4>Y'F[[R*`^JE3^C%2`&=MGQ -MYUC?@G?,%@:MX&N0VXZ*UXRZYM"=ALD240=3)>IN/M3G0%]EU&<`*L:[K\>1 -MZ+4^%NC`0M>602JI-!IEY@V/4ZG#&LNP\%@-O -MJ">%4#L*)U0`V_2OUHF-[7H$S,Y]"MF+FLR@5"/ZG#>.8XP) -M=.?196%/U4;UHG=YQ/HDE.PF3,41%VGSA72MRJ%T'NH:VZ;:,82VW6A4'+;? -M6!V`IG%-)S4VWNV:FJ9P+V$^]&6Z9,'9+_.;"O28C/X42]'D5J7@ZF\2IR:C -M127+_^GNWL.KJ`X$@%^A:J2NFVZM=5MV>U5VR]L`'QKI+MZB8&!!(UJ7@L@- -M+\,[AH=13+VLK:`5B\4'/AFMCQ2MTO6%UL<5JB*%%A5JM,5>P=K4ZBZ*L+1% -M=W/O_$Z2&X/:?OOUC_H'OYZ9\YXS9\[6\[>-9R2XMDUOS4)M553O#K'IT_JIQ=)O)U87B0Q-8 -M[_8S;;[5O=M>EGN',>)J:%?KA-ZRQBX\1I8L/%+6YEI1>.._3^'UJWFM<5,? -M\6IT]V3-U*JD&K:=>0M32)O*MSZ.UC9A:''^<5AE%:;I#Y42KWP*__9Q%]*E -M=8%6N!7IU5'2[LF957,+Q<;)XGSVOY9)%?[MJ)TM69Q?>/^_I:'Y_UHN#.T: -MV2YEFQ3QO57K@BCNL]95T;QI$PBL-0N-#?^M$1AI=PKOU(N)/BG -M.,FX+X]/AH=_DX7'.]M<.+O%<0K3>^'%S_S*+$3^^&O8?J]-]?'.^OKV.]O/ -MKT43;,L,.WMD\XE6/,]^TEFV:#E?_%A__M&_PGU'/CQWRI3\^R3Y&K:Y$C6G -M+OQ3:%_AOC7?EN;SNCG/CI;T<46;9^KFJ2;^WUW:3Q^N8?V*9J,VJ@57_JI-YN`MW?'/])YL%/LK;*C[!QTZ:._Q.6 -M+H5_NG@Y(Y^V:%P.KFW=-WQ8\;Y:W./RZXD_O_!"ZOT6/W3D&4,_ -MM@+YQ][__`H44N^W`F=6##WU(RO0[DB$WBB^4_OP^;K_D[=POK4;@?'Q[7CI -MU_:^LH.UGPJU3]LV@SZ%,O,G9:_VB\*.,XTSCKN]9679G$TA9ASJ*)^.UIMA -MALKGDW_(N3B6LZKMV12_=9!/$K\J5'1=*+Y]CT^*[O$`B`]'66&B:#F9=8[O -M`K5+;5B%'PJ*][>>HO&74^+OFLY)3)HS,_\1H<*+(?.J"H^RSZF=EG^UY:_H -MO]8W?%M>$XY?/VY]67ALV_CA[Q+AN\7A^\/A.\/AN\#A^[SA^[CA>[#A^ZKA -M.ZGA>Z?ANZ7A>Z7A.Z7A>Z/ANZ#A>Y;A>VGA>V/A^U_A^U[AOUQOS]NN]3SN -M"Y[/W>#W[W/]GGVHW[.7Q&9J.#GAN76_IW^="_PN_C?"A\7N?,_SZ/VE&Z1= -M!RGW/<\#?\;SP%O$DU\T03UZ>V[;\^Z9$X2KE%L6ITL)ISXGW$/^)\7Q)Q\5 -M[\]-UI[^_KYB?_HX/J^?QFN/^-WWZO=;X_VK]6_F?OE=$&]?$MG.Y"GQ_NK? -M2Z_QT_KK0.6$ -MXW&KOX>\JSS]GIH6.R:,)^\C1(NE/X>#M=]QS-XD_4#C2KFIDG/49U+L/RHW:;Q&]B=O,EZDBXS;7!_M'6#[..4\H)[:F:M5+^,^TSNV -MSG&*QMK_5!S_Z/`^QF['[P/CUKAK#.-=?T4SUAPOWFG*U=][Y9]^ -M7/WL3[PL7"G^$X[S.N6_HI\/4,XARG4^[C0?I7K%X67:=Z+R1XQ0Y?[/Z)^'XYAROW*1PWJCG0MN?CMUX2#@OZ7Q+_%I_ -MFS\3@Y3WFO-&_^6FBJ^?(NG2L\4W?V9VJV<_UX>3U<>X3*M_H^.7"_WQ$^69 -M?U/A>.F?]`'RK5#.?&'MFSW9_-1+/L?*WSR;Z*G^CFMJD'8XWS/FA;3XV7_5 -M3^OURSOZR3R6-"XR/[-_@?*,ZXSRTN&X#U=>3^>]ZTGV7IX:>Z3CES,.\:YE/]D#C0_F?U;X\P;J0W -M/A,W"W?1G^'\=QZGG^E4=%YF9B7",AS3MX,Z_A%:SG7$YDFLL`DSAV1/%[@(.$CV`YC^=&[P-NYG-\E'=Q!4_C8)9RE_?NWF03 -M'^!*+F$%1[$\I//>X"K>RP;6LYH#>2P_S?`^XU8^PDU\F`]R-9-]X_%4,2H. -M#^`_L)0EG.Z]PM,YBN7\0+P]W,7?\I?3#W5<;NY'8VQ<^R"S]0W[WZ2MK),>^M -M=F(9?R'=5F:YBK$=8#K,R_B -M!(YDEDV)EKV:=[94<=FX0V>,TTOEB\KQ=ME -M_S8.J8K]9_XM5XA_$VNXWOZ'>!WK.)[=W3=%TC7PT(G.5R:XVO[(\XZKK>OO -MY7*F_&ZR7OQ&VQ.>;\R%\(OA_Q_+?,TR=F4)K^657,IO$^TO](/WA(^)VK]"^(5.M7W@<^[,G#V4G-DJ_F=G07]S(-5S- -M!MXGGXA7E.^3)18MQ^L'0"69VJC=S_ZU^0?FE/R5__15ULK[L3.'H`(;MPLF$[?^K_."U -MZO&V\AR7Z+N\2O\X;M%]XO^.6?5_EB^(_YC\;<_=H_TOB;?9_C7A/E^Z'XJ_ -M3?R<>JT2/XRSGZN/WP%35TN_ECOD^TOA#>+9GMJJ'K]2GG&54Z_<=N4^K%SF -M-@H_+M]E\M.^;+UXK]FN'6GAG/9$RHU>E=]_BG<;]4/J(>D>U)X?A-_SI/.[ -M:<;^I'8F'E&?X"^4]XK\7J;S."&_S!;EORB_:X1O%O\[MC-G7DCXG26ZTG;' -M-;5.^?+)&1^1OQ-DA=-A^_/R_Y'Z,&=>B1X5_T;QC)M(>='=MFMW]%/Q@YOL -M9^(ZX3#>]7?Z)W3>9Y\6/^3_?>TSOK/":?-C\IOR,RZ3SJ.4\9+1?QGEIQ=I -M9T:Z%;8+YRZVO8%WR5NL^2+GN"2?4\YZAGE`_5/O"KM.Y(R'1!@7X;S27YO.B^>IM7R8]_`VWL#E -M7,IO,P5*6\(\UUH5\F[_A-K[$%[B) -MZ_@X'^;]O(<-O(,W\G+6E7,2%G,_9K.94ICF>9_%TCN0P#N$@'L^![,N>[,YN -M_!+_GJ7LPL[<-\M]*W?S7;[-)N[@-OZ[R%UW`9 -ME_)2+F(]+^!\UG(&I_(#]7\P=LXES6LYF2> -MP[,YEO_.K_$,CN(I',)_X0D\C@-8QC[LR2^S&X]B5WZ!G^?A_#N6\C"6\$!V -MYOLS8O_`O=S#]_@._XMO\4W^AMOX(A_G[;R2B[F(%[*.TYCFR>S!SX3Z3O?[ -M-=?R+B[FA9S$?V,_]F0I?S?-WR$8\0+.915'YP.\FE=Q -M,>LXB1,XFL-9P4$L9Q\F^3GN. -MN)<[N8R;N9Z-K.9Y7,$LE_`;7,T&EJM'3C@E/$/X1'_W*V!@_51O^ ->?NYW1.NU2OF>SCK6O&M>J.WXO>G_`\5UG,-@Q@(` -` -end diff --git a/sys/boot/alpha/cdboot/version b/sys/boot/alpha/cdboot/version index 75279a0eb6..8924148a38 100644 --- a/sys/boot/alpha/cdboot/version +++ b/sys/boot/alpha/cdboot/version @@ -1,9 +1,11 @@ -$FreeBSD: src/sys/boot/alpha/cdboot/version,v 1.2.2.1 2000/07/18 04:15:56 obrien Exp $ -$DragonFly: src/sys/boot/alpha/cdboot/Attic/version,v 1.2 2003/06/17 04:28:16 dillon Exp $ +$FreeBSD: src/sys/boot/alpha/cdboot/version,v 1.5 2001/12/11 00:49:33 jhb Exp $ +$DragonFly: src/sys/boot/alpha/cdboot/Attic/version,v 1.3 2003/11/10 06:08:26 dillon Exp $ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important. Make sure the current version number is on line 6. +1.2: New calling conventions for fopen. +1.1: New semantics for finding the kernel, new boot. 1.0: Released working DEC Alpha version. 0.1: Initial i386 version, germinated from the NetBSD i386 standalone, but enormously modified. diff --git a/sys/boot/alpha/common/Makefile.common b/sys/boot/alpha/common/Makefile.common index 725f03e41c..a021085bc9 100644 --- a/sys/boot/alpha/common/Makefile.common +++ b/sys/boot/alpha/common/Makefile.common @@ -1,5 +1,5 @@ -# $FreeBSD: src/sys/boot/alpha/common/Makefile.common,v 1.4.2.5 2002/07/17 12:34:16 ru Exp $ -# $DragonFly: src/sys/boot/alpha/common/Attic/Makefile.common,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD$ +# $DragonFly: src/sys/boot/alpha/common/Attic/Makefile.common,v 1.3 2003/11/10 06:08:29 dillon Exp $ # # Common Alpha loader build rules @@ -11,15 +11,17 @@ SRCS+= main.c conf.c SRCS+= dev_net.c .endif +.if !defined(NOFORTH) # Enable BootForth BOOT_FORTH= yes -CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/alpha CFLAGS+= -DBOOT_FORTH +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/alpha .if exists(${.OBJDIR}/../../ficl/libficl.a) LIBFICL= ${.OBJDIR}/../../ficl/libficl.a .else LIBFICL= ${.CURDIR}/../../ficl/libficl.a .endif +.endif # Always add MI sources .PATH: ${.CURDIR}/../../common @@ -42,20 +44,18 @@ STRIP= BINDIR?= /boot INSTALLFLAGS?= -b -all: ${BASE} +all: ${BASE} ${BASE}.help vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} ${CC} -c vers.c -${BASE}: ${BASE}.sym ${BASE}.help - objcopy -O binary ${BASE}.sym ${BASE} - -${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBFICL} ${LIBALPHA} ${CRT} vers.o setdef0.o setdef1.o +${BASE}: ${OBJS} ${LIBSTAND} ${LIBFICL} ${LIBALPHA} ${CRT} vers.o ${LD} -o ${BASE}.sym -M -e start -N -Ttext ${LOAD_ADDRESS} \ - ${CRT} setdef0.o ${OBJS} setdef1.o vers.o \ + ${CRT} ${OBJS} vers.o \ -L${DESTDIR}${LIBDIR} ${LIBSTAND} ${LIBALPHA} ${LIBFICL} ${LIBSTAND} \ >${.OBJDIR}/${BASE}.list + objcopy -O binary ${BASE}.sym ${BASE} CLEANFILES+= ${BASE}.help ${BASE}.help: help.common help.alpha @@ -86,10 +86,6 @@ beforeinstall: start.o: ${.CURDIR}/../libalpha/start.S ${CC} -c ${CFLAGS} $< -setdef0.o: setdefs.h - -setdef1.o: setdefs.h - machine: ln -sf ${.CURDIR}/../../../alpha/include machine @@ -97,9 +93,4 @@ CLEANFILES+= machine .include -.ORDER: setdefs.h setdef0.c setdef1.c -setdefs.h setdef0.c setdef1.c: ${OBJS} - @echo Generating linker sets - @gensetdefs ${OBJS} - beforedepend ${OBJS}: machine diff --git a/sys/boot/alpha/common/conf.c b/sys/boot/alpha/common/conf.c index 7598e9853d..55ad522226 100644 --- a/sys/boot/alpha/common/conf.c +++ b/sys/boot/alpha/common/conf.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/alpha/common/conf.c,v 1.1.2.1 2000/05/04 13:50:47 ps Exp $ - * $DragonFly: src/sys/boot/alpha/common/Attic/conf.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/alpha/common/conf.c,v 1.4 2002/12/19 19:34:58 jake Exp $ + * $DragonFly: src/sys/boot/alpha/common/Attic/conf.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ #include @@ -66,7 +66,7 @@ struct fs_ops *file_system[] = { #ifdef LOADER_NET_SUPPORT &nfs_fsops, #endif - &zipfs_fsops, + &gzipfs_fsops, NULL }; @@ -82,9 +82,9 @@ struct netif_driver *netif_drivers[] = { * Sort formats so that those that can detect based on arguments * rather than reading the file go first. */ -extern struct module_format alpha_elf; +extern struct file_format alpha_elf; -struct module_format *module_formats[] = { +struct file_format *file_formats[] = { &alpha_elf, NULL }; diff --git a/sys/boot/alpha/common/main.c b/sys/boot/alpha/common/main.c index 566e81290c..9cc6023cd2 100644 --- a/sys/boot/alpha/common/main.c +++ b/sys/boot/alpha/common/main.c @@ -24,8 +24,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/alpha/common/main.c,v 1.11.2.2 2001/03/04 05:14:50 obrien Exp $ - * $DragonFly: src/sys/boot/alpha/common/Attic/main.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/alpha/common/main.c,v 1.13 2000/10/25 23:36:01 dfr Exp $ + * $DragonFly: src/sys/boot/alpha/common/Attic/main.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ diff --git a/sys/boot/alpha/libalpha/Makefile b/sys/boot/alpha/libalpha/Makefile index 2fc47a9de8..c6c9756aae 100644 --- a/sys/boot/alpha/libalpha/Makefile +++ b/sys/boot/alpha/libalpha/Makefile @@ -1,9 +1,10 @@ -# $FreeBSD: src/sys/boot/alpha/libalpha/Makefile,v 1.7.2.2 2002/07/19 18:46:28 ru Exp $ -# $DragonFly: src/sys/boot/alpha/libalpha/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/alpha/libalpha/Makefile,v 1.13 2002/05/13 10:53:24 ru Exp $ +# $DragonFly: src/sys/boot/alpha/libalpha/Attic/Makefile,v 1.3 2003/11/10 06:08:29 dillon Exp $ LIB= alpha INTERNALLIB= true +CFLAGS+= -ffreestanding #CFLAGS+= -DDISK_DEBUG #CPPFLAGS+= -DNO_DISKLABEL #CPPFLAGS+= -DSAVE_MEMORY diff --git a/sys/boot/alpha/libalpha/OSFpal.c b/sys/boot/alpha/libalpha/OSFpal.c index 5fdbedd207..9c1d245a2f 100644 --- a/sys/boot/alpha/libalpha/OSFpal.c +++ b/sys/boot/alpha/libalpha/OSFpal.c @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/OSFpal.c,v 1.2.2.1 2000/07/07 00:20:49 obrien Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/OSFpal.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From $NetBSD: OSFpal.c,v 1.5 1998/06/24 01:33:19 ross Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/OSFpal.c,v 1.3 2000/06/03 08:24:37 dfr Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/OSFpal.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/alpha_copy.c b/sys/boot/alpha/libalpha/alpha_copy.c index 54b952e058..af129874ac 100644 --- a/sys/boot/alpha/libalpha/alpha_copy.c +++ b/sys/boot/alpha/libalpha/alpha_copy.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/alpha/libalpha/alpha_copy.c,v 1.4.2.1 2000/12/28 13:12:24 ps Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/alpha_copy.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/alpha_copy.c,v 1.5 2000/08/03 09:49:44 jhb Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/alpha_copy.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ /* * MD primitives supporting placement of module data diff --git a/sys/boot/alpha/libalpha/alpha_module.c b/sys/boot/alpha/libalpha/alpha_module.c index e5cd2a6ebe..9f8e4ffe44 100644 --- a/sys/boot/alpha/libalpha/alpha_module.c +++ b/sys/boot/alpha/libalpha/alpha_module.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/alpha/libalpha/alpha_module.c,v 1.3 1999/08/28 00:39:26 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/alpha_module.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/alpha_module.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/bbinfo.h b/sys/boot/alpha/libalpha/bbinfo.h index fe4be749a0..c5116f43f9 100644 --- a/sys/boot/alpha/libalpha/bbinfo.h +++ b/sys/boot/alpha/libalpha/bbinfo.h @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/bbinfo.h,v 1.2 1999/08/28 00:39:26 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/bbinfo.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From $NetBSD: bbinfo.h,v 1.2 1997/04/06 08:40:57 cgd Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/bbinfo.h,v 1.2 1999/08/28 00:39:26 peter Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/bbinfo.h,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/bootinfo.c b/sys/boot/alpha/libalpha/bootinfo.c index aa1b3a272d..f9040e0c8a 100644 --- a/sys/boot/alpha/libalpha/bootinfo.c +++ b/sys/boot/alpha/libalpha/bootinfo.c @@ -23,14 +23,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/alpha/libalpha/bootinfo.c,v 1.9.2.1 2001/03/04 05:20:26 obrien Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/bootinfo.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD$ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/bootinfo.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ #include #include #include -#include #include #include #include @@ -126,19 +125,19 @@ bi_copyenv(vm_offset_t addr) vm_offset_t bi_copymodules(vm_offset_t addr) { - struct loaded_module *mp; - struct module_metadata *md; + struct preloaded_file *fp; + struct file_metadata *md; /* start with the first module on the list, should be the kernel */ - for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) { - - MOD_NAME(addr, mp->m_name); /* this field must come first */ - MOD_TYPE(addr, mp->m_type); - if (mp->m_args) - MOD_ARGS(addr, mp->m_args); - MOD_ADDR(addr, mp->m_addr); - MOD_SIZE(addr, mp->m_size); - for (md = mp->m_metadata; md != NULL; md = md->md_next) + for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { + + MOD_NAME(addr, fp->f_name); /* this field must come first */ + MOD_TYPE(addr, fp->f_type); + if (fp->f_args) + MOD_ARGS(addr, fp->f_args); + MOD_ADDR(addr, fp->f_addr); + MOD_SIZE(addr, fp->f_size); + for (md = fp->f_metadata; md != NULL; md = md->md_next) if (!(md->md_type & MODINFOMD_NOCOPY)) MOD_METADATA(addr, md); } @@ -154,16 +153,16 @@ bi_copymodules(vm_offset_t addr) */ int bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save, - struct loaded_module *mp) + struct preloaded_file *fp) { char *rootdevname; struct alpha_devdesc *rootdev; - struct loaded_module *xp; + struct preloaded_file *xp; vm_offset_t addr, bootinfo_addr; u_int pad; char *kernelname; vm_offset_t ssym, esym; - struct module_metadata *md; + struct file_metadata *md; /* * Allow the environment variable 'rootdev' to override the supplied device @@ -182,9 +181,9 @@ bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save, free(rootdev); ssym = esym = 0; - if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL) + if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL) ssym = *((vm_offset_t *)&(md->md_data)); - if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL) + if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL) esym = *((vm_offset_t *)&(md->md_data)); if (ssym == 0 || esym == 0) ssym = esym = 0; /* sanity */ @@ -194,9 +193,9 @@ bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save, /* find the last module in the chain */ addr = 0; - for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) { - if (addr < (xp->m_addr + xp->m_size)) - addr = xp->m_addr + xp->m_size; + for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { + if (addr < (xp->f_addr + xp->f_size)) + addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ pad = (u_int)addr & PAGE_MASK; diff --git a/sys/boot/alpha/libalpha/common.h b/sys/boot/alpha/libalpha/common.h index 7a208fc630..00404dd128 100644 --- a/sys/boot/alpha/libalpha/common.h +++ b/sys/boot/alpha/libalpha/common.h @@ -1,12 +1,12 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/common.h,v 1.2 1999/08/28 00:39:26 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/common.h,v 1.3 2003/08/27 11:42:33 rob Exp $ * From: $NetBSD: common.h,v 1.2 1998/01/05 07:02:48 perry Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/common.h,v 1.3 2002/06/29 02:32:32 peter Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/common.h,v 1.4 2003/11/10 06:08:29 dillon Exp $ */ -int prom_open (char*, int); -void OSFpal (void); -void halt (void); -u_int64_t prom_dispatch (int, ...); -int cpu_number (void); -void switch_palcode (void); +int prom_open(char*, int); +void OSFpal(void); +void halt(void); +u_int64_t prom_dispatch(int, ...); +int cpu_number(void); +void switch_palcode(void); diff --git a/sys/boot/alpha/libalpha/delay.c b/sys/boot/alpha/libalpha/delay.c index c2ba409d12..67f8971072 100644 --- a/sys/boot/alpha/libalpha/delay.c +++ b/sys/boot/alpha/libalpha/delay.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/alpha/libalpha/delay.c,v 1.2 1999/08/28 00:39:27 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/delay.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/delay.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ #include diff --git a/sys/boot/alpha/libalpha/devicename.c b/sys/boot/alpha/libalpha/devicename.c index 705e4a863b..b1848aea33 100644 --- a/sys/boot/alpha/libalpha/devicename.c +++ b/sys/boot/alpha/libalpha/devicename.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/alpha/libalpha/devicename.c,v 1.4 1999/08/28 00:39:27 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/devicename.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/devicename.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ */ #include diff --git a/sys/boot/alpha/libalpha/elf_freebsd.c b/sys/boot/alpha/libalpha/elf_freebsd.c index e666644e27..a821f42788 100644 --- a/sys/boot/alpha/libalpha/elf_freebsd.c +++ b/sys/boot/alpha/libalpha/elf_freebsd.c @@ -1,6 +1,8 @@ -/* $FreeBSD: src/sys/boot/alpha/libalpha/elf_freebsd.c,v 1.8.2.2 2001/03/04 05:21:25 obrien Exp $ */ -/* $DragonFly: src/sys/boot/alpha/libalpha/Attic/elf_freebsd.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ -/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */ +/* + * $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/elf_freebsd.c,v 1.12 2003/05/01 03:56:28 peter Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/elf_freebsd.c,v 1.3 2003/11/10 06:08:29 dillon Exp $ + */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -91,30 +93,30 @@ #define _KERNEL -static int elf_exec(struct loaded_module *amp); +static int elf64_exec(struct preloaded_file *afp); int bi_load(struct bootinfo_v1 *, vm_offset_t *, - struct loaded_module *); + struct preloaded_file *); -struct module_format alpha_elf = { elf_loadmodule, elf_exec }; +struct file_format alpha_elf = { elf64_loadfile, elf64_exec }; vm_offset_t ffp_save, ptbr_save; static int -elf_exec(struct loaded_module *mp) +elf64_exec(struct preloaded_file *fp) { static struct bootinfo_v1 bootinfo_v1; - struct module_metadata *md; + struct file_metadata *md; Elf_Ehdr *hdr; int err; int flen; - if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL) + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); /* XXX actually EFUCKUP */ hdr = (Elf_Ehdr *)&(md->md_data); /* XXX ffp_save does not appear to be used in the kernel.. */ bzero(&bootinfo_v1, sizeof(bootinfo_v1)); - err = bi_load(&bootinfo_v1, &ffp_save, mp); + err = bi_load(&bootinfo_v1, &ffp_save, fp); if (err) return(err); @@ -132,8 +134,8 @@ elf_exec(struct loaded_module *mp) /* * Append the boot command flags. */ - if (mp->m_args != NULL && *mp->m_args != '\0') { - const char *p = mp->m_args; + if (fp->f_args != NULL && *fp->f_args != '\0') { + const char *p = fp->f_args; do { if (*p == '-') { @@ -149,7 +151,7 @@ elf_exec(struct loaded_module *mp) bootinfo_v1.boot_flags[flen] = '\0'; } - printf("Entering %s at 0x%lx...\n", mp->m_name, hdr->e_entry); + printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); closeall(); dev_cleanup(); alpha_pal_imb(); diff --git a/sys/boot/alpha/libalpha/getsecs.c b/sys/boot/alpha/libalpha/getsecs.c index 8510719f17..8b74645248 100644 --- a/sys/boot/alpha/libalpha/getsecs.c +++ b/sys/boot/alpha/libalpha/getsecs.c @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/getsecs.c,v 1.2 1999/08/28 00:39:27 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/getsecs.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From: $NetBSD: getsecs.c,v 1.5 1998/01/05 07:02:49 perry Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/getsecs.c,v 1.2 1999/08/28 00:39:27 peter Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/getsecs.c,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ #include diff --git a/sys/boot/alpha/libalpha/libalpha.h b/sys/boot/alpha/libalpha/libalpha.h index 6072139cc0..035428adf0 100644 --- a/sys/boot/alpha/libalpha/libalpha.h +++ b/sys/boot/alpha/libalpha/libalpha.h @@ -1,5 +1,7 @@ -/* $FreeBSD: src/sys/boot/alpha/libalpha/libalpha.h,v 1.5.2.1 2000/12/28 13:12:24 ps Exp $ */ -/* $DragonFly: src/sys/boot/alpha/libalpha/Attic/libalpha.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/alpha/libalpha/libalpha.h,v 1.6 2000/08/03 09:49:44 jhb Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/libalpha.h,v 1.3 2003/11/10 06:08:30 dillon Exp $ + */ /* * Copyright (c) 1996 diff --git a/sys/boot/alpha/libalpha/pal.S b/sys/boot/alpha/libalpha/pal.S index 15959a1aa2..414983c8a1 100644 --- a/sys/boot/alpha/libalpha/pal.S +++ b/sys/boot/alpha/libalpha/pal.S @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/pal.S,v 1.2.2.1 2001/08/03 07:14:52 obrien Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/pal.S,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From: $NetBSD: pal.s,v 1.12 1998/02/27 03:44:53 thorpej Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/pal.S,v 1.3 2001/05/28 09:52:21 obrien Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/pal.S,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/prom.c b/sys/boot/alpha/libalpha/prom.c index 8b29a66b80..7c206b9ae2 100644 --- a/sys/boot/alpha/libalpha/prom.c +++ b/sys/boot/alpha/libalpha/prom.c @@ -1,6 +1,8 @@ -/* $FreeBSD: src/sys/boot/alpha/libalpha/prom.c,v 1.3 1999/08/28 00:39:28 peter Exp $ */ -/* $DragonFly: src/sys/boot/alpha/libalpha/Attic/prom.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ -/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */ +/* + * $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/prom.c,v 1.3 1999/08/28 00:39:28 peter Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/prom.c,v 1.3 2003/11/10 06:08:30 dillon Exp $ + */ /* * Mach Operating System diff --git a/sys/boot/alpha/libalpha/prom_disp.S b/sys/boot/alpha/libalpha/prom_disp.S index a7a1c8dd27..1af68154a8 100644 --- a/sys/boot/alpha/libalpha/prom_disp.S +++ b/sys/boot/alpha/libalpha/prom_disp.S @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/prom_disp.S,v 1.2 1999/08/28 00:39:28 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/prom_disp.S,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From: $NetBSD: prom_disp.S,v 1.2 1997/04/06 08:41:00 cgd Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/prom_disp.S,v 1.2 1999/08/28 00:39:28 peter Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/prom_disp.S,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/prom_swpal.S b/sys/boot/alpha/libalpha/prom_swpal.S index 44d7a1a38e..a314bd089f 100644 --- a/sys/boot/alpha/libalpha/prom_swpal.S +++ b/sys/boot/alpha/libalpha/prom_swpal.S @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/prom_swpal.S,v 1.2 1999/08/28 00:39:29 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/prom_swpal.S,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From: $NetBSD: prom_swpal.S,v 1.2 1997/04/06 08:41:01 cgd Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/prom_swpal.S,v 1.2 1999/08/28 00:39:29 peter Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/prom_swpal.S,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/reboot.c b/sys/boot/alpha/libalpha/reboot.c index 9baad2f3bd..ace99df70d 100644 --- a/sys/boot/alpha/libalpha/reboot.c +++ b/sys/boot/alpha/libalpha/reboot.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/alpha/libalpha/reboot.c,v 1.2 1999/08/28 00:39:29 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/reboot.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/reboot.c,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ #include diff --git a/sys/boot/alpha/libalpha/srmdisk.c b/sys/boot/alpha/libalpha/srmdisk.c index 7f9f80172d..4773c1270d 100644 --- a/sys/boot/alpha/libalpha/srmdisk.c +++ b/sys/boot/alpha/libalpha/srmdisk.c @@ -24,8 +24,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/alpha/libalpha/srmdisk.c,v 1.8.2.2 2001/08/01 20:52:03 mjacob Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/srmdisk.c,v 1.3 2003/11/09 02:22:29 dillon Exp $ + * $FreeBSD$ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/srmdisk.c,v 1.4 2003/11/10 06:08:30 dillon Exp $ */ /* @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -153,7 +152,7 @@ bd_print(int verbose) static int bd_open(struct open_file *f, ...) { - __va_list args; + va_list args; struct alpha_devdesc *dev; struct dos_partition *dptr; struct open_disk *od; @@ -163,9 +162,9 @@ bd_open(struct open_file *f, ...) int unit, fd; prom_return_t ret; - __va_start(args, f); - dev = __va_arg(args, struct alpha_devdesc*); - __va_end(args); + va_start(args, f); + dev = va_arg(args, struct alpha_devdesc*); + va_end(args); unit = dev->d_kind.srmdisk.unit; if (unit >= nbdinfo) { diff --git a/sys/boot/alpha/libalpha/srmnet.c b/sys/boot/alpha/libalpha/srmnet.c index 66e4c4cc5c..28c777fee2 100644 --- a/sys/boot/alpha/libalpha/srmnet.c +++ b/sys/boot/alpha/libalpha/srmnet.c @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/srmnet.c,v 1.4 1999/09/06 18:32:40 dfr Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/srmnet.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From: $NetBSD: if_prom.c,v 1.10 1997/09/06 14:08:33 drochner Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/srmnet.c,v 1.4 1999/09/06 18:32:40 dfr Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/srmnet.c,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/start.S b/sys/boot/alpha/libalpha/start.S index 88c769cef5..c69d699d08 100644 --- a/sys/boot/alpha/libalpha/start.S +++ b/sys/boot/alpha/libalpha/start.S @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/alpha/libalpha/start.S,v 1.6.2.2 2001/03/04 05:23:01 obrien Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/start.S,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From: $NetBSD: start.S,v 1.4 1998/03/28 00:54:15 cgd Exp $ + * $FreeBSD: src/sys/boot/alpha/libalpha/start.S,v 1.9 2001/03/04 04:38:14 obrien Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/start.S,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ /* diff --git a/sys/boot/alpha/libalpha/time.c b/sys/boot/alpha/libalpha/time.c index 08baf72893..0142f2047f 100644 --- a/sys/boot/alpha/libalpha/time.c +++ b/sys/boot/alpha/libalpha/time.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/alpha/libalpha/time.c,v 1.2 1999/08/28 00:39:30 peter Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/time.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/alpha/libalpha/Attic/time.c,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ #include diff --git a/sys/boot/alpha/loader/Makefile b/sys/boot/alpha/loader/Makefile index 08b9e4cb81..a9474b8752 100644 --- a/sys/boot/alpha/loader/Makefile +++ b/sys/boot/alpha/loader/Makefile @@ -1,5 +1,5 @@ -# $FreeBSD: src/sys/boot/alpha/loader/Makefile,v 1.2.2.4 2000/10/30 10:02:47 obrien Exp $ -# $DragonFly: src/sys/boot/alpha/loader/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/alpha/loader/Makefile,v 1.7 2002/05/10 09:26:29 obrien Exp $ +# $DragonFly: src/sys/boot/alpha/loader/Attic/Makefile,v 1.3 2003/11/10 06:08:30 dillon Exp $ BASE= loader PROG= ${BASE} @@ -8,6 +8,6 @@ INSTALL_HELP= yes LOAD_ADDRESS= ${SECONDARY_LOAD_ADDRESS} # Only disk support -CFLAGS+= -DLOADER_DISK_SUPPORT # -DLOADER_EXT2FS_SUPPORT +CFLAGS+= -ffreestanding -DLOADER_DISK_SUPPORT # -DLOADER_EXT2FS_SUPPORT .include <${.CURDIR}/../common/Makefile.common> diff --git a/sys/boot/alpha/loader/version b/sys/boot/alpha/loader/version index f128ee2083..45ace22905 100644 --- a/sys/boot/alpha/loader/version +++ b/sys/boot/alpha/loader/version @@ -1,9 +1,11 @@ -$FreeBSD: src/sys/boot/alpha/loader/version,v 1.2.2.2 2000/09/03 02:46:58 obrien Exp $ -$DragonFly: src/sys/boot/alpha/loader/Attic/version,v 1.2 2003/06/17 04:28:16 dillon Exp $ +$FreeBSD: src/sys/boot/alpha/loader/version,v 1.6 2001/12/11 00:49:33 jhb Exp $ +$DragonFly: src/sys/boot/alpha/loader/Attic/version,v 1.3 2003/11/10 06:08:30 dillon Exp $ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important. Make sure the current version number is on line 6. +1.2: New calling conventions for fopen. +1.1: New semantics for finding the kernel, new boot. 1.0: Released working DEC Alpha version. 0.3: Set/getenv&cia, copyin/out. 0.2: FICL added to Alpha. diff --git a/sys/boot/alpha/netboot/Makefile b/sys/boot/alpha/netboot/Makefile index 1d7afac0ca..67edb4ec03 100644 --- a/sys/boot/alpha/netboot/Makefile +++ b/sys/boot/alpha/netboot/Makefile @@ -1,6 +1,6 @@ -# $FreeBSD: src/sys/boot/alpha/netboot/Makefile,v 1.8.2.1 2000/07/06 23:29:47 obrien Exp $ -# $DragonFly: src/sys/boot/alpha/netboot/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ -# $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $ +# $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $ +# $FreeBSD: src/sys/boot/alpha/netboot/Makefile,v 1.10 2002/05/10 09:26:29 obrien Exp $ +# $DragonFly: src/sys/boot/alpha/netboot/Attic/Makefile,v 1.3 2003/11/10 06:08:30 dillon Exp $ BASE= netboot PROG= ${BASE} @@ -8,7 +8,7 @@ NOMAN= NEWVERSWHAT= "SRM net boot" alpha LOAD_ADDRESS= ${PRIMARY_LOAD_ADDRESS} -CFLAGS+= -DLOADER_NET_SUPPORT +CFLAGS+= -ffreestanding -DLOADER_NET_SUPPORT .include <${.CURDIR}/../common/Makefile.common> diff --git a/sys/boot/alpha/netboot/version b/sys/boot/alpha/netboot/version index 0369510b00..6ad6dd56d1 100644 --- a/sys/boot/alpha/netboot/version +++ b/sys/boot/alpha/netboot/version @@ -1,8 +1,13 @@ -$FreeBSD: src/sys/boot/alpha/netboot/version,v 1.2 1999/08/28 00:39:32 peter Exp $ -$DragonFly: src/sys/boot/alpha/netboot/Attic/version,v 1.2 2003/06/17 04:28:16 dillon Exp $ +$FreeBSD: src/sys/boot/alpha/netboot/version,v 1.3 2002/01/11 00:09:59 jhb Exp $ +$DragonFly: src/sys/boot/alpha/netboot/Attic/version,v 1.3 2003/11/10 06:08:30 dillon Exp $ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important. Make sure the current version number is on line 6. +1.2: New calling conventions for fopen. +1.1: New semantics for finding the kernel, new boot. +1.0: Released working DEC Alpha version. +0.3: Set/getenv&cia, copyin/out. +0.2: FICL added to Alpha. 0.1: Initial i386 version, germinated from the NetBSD i386 standalone, but enormously modified. diff --git a/sys/boot/arc/Makefile b/sys/boot/arc/Makefile index d21d921d5d..97864cb5e8 100644 --- a/sys/boot/arc/Makefile +++ b/sys/boot/arc/Makefile @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/boot/arc/Makefile,v 1.2 1999/08/28 00:39:33 peter Exp $ -# $DragonFly: src/sys/boot/arc/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $DragonFly: src/sys/boot/arc/Attic/Makefile,v 1.3 2003/11/10 06:08:30 dillon Exp $ SUBDIR= lib SUBDIR+= loader diff --git a/sys/boot/arc/Makefile.inc b/sys/boot/arc/Makefile.inc index c041402741..502d903c1c 100644 --- a/sys/boot/arc/Makefile.inc +++ b/sys/boot/arc/Makefile.inc @@ -1,5 +1,5 @@ -# $FreeBSD: src/sys/boot/arc/Makefile.inc,v 1.1.1.1.2.1 2000/07/06 23:29:47 obrien Exp $ -# $DragonFly: src/sys/boot/arc/Attic/Makefile.inc,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/arc/Makefile.inc,v 1.2 2000/05/01 20:26:21 peter Exp $ +# $DragonFly: src/sys/boot/arc/Attic/Makefile.inc,v 1.3 2003/11/10 06:08:30 dillon Exp $ # Options used when building app-specific libalpha components LOAD_ADDRESS= 0xffffffff80900000 DPADD+= ${DESTDIR}/${LIBDIR}/libstand.a diff --git a/sys/boot/arc/include/arcfuncs.h b/sys/boot/arc/include/arcfuncs.h index 36dadc6663..1c4b2bec48 100644 --- a/sys/boot/arc/include/arcfuncs.h +++ b/sys/boot/arc/include/arcfuncs.h @@ -24,8 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/include/arcfuncs.h,v 1.2 1999/08/28 00:39:34 peter Exp $ - * $DragonFly: src/sys/boot/arc/include/Attic/arcfuncs.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ - * + * $DragonFly: src/sys/boot/arc/include/Attic/arcfuncs.h,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ #ifdef __GNUC__ diff --git a/sys/boot/arc/include/arctypes.h b/sys/boot/arc/include/arctypes.h index 2eb02ebd2b..5445babf41 100644 --- a/sys/boot/arc/include/arctypes.h +++ b/sys/boot/arc/include/arctypes.h @@ -24,8 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/include/arctypes.h,v 1.2 1999/08/28 00:39:34 peter Exp $ - * $DragonFly: src/sys/boot/arc/include/Attic/arctypes.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ - * + * $DragonFly: src/sys/boot/arc/include/Attic/arctypes.h,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ #ifndef _ARC_TYPES_H_ diff --git a/sys/boot/arc/include/libarc.h b/sys/boot/arc/include/libarc.h index b39180d65f..4f3acbdc5b 100644 --- a/sys/boot/arc/include/libarc.h +++ b/sys/boot/arc/include/libarc.h @@ -1,6 +1,3 @@ -/* $FreeBSD: src/sys/boot/arc/include/libarc.h,v 1.2 1999/08/28 00:39:34 peter Exp $ */ -/* $DragonFly: src/sys/boot/arc/include/Attic/libarc.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ - /* * Copyright (c) 1996 * Matthias Drochner. All rights reserved. @@ -31,6 +28,8 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * $FreeBSD: src/sys/boot/arc/include/libarc.h,v 1.2 1999/08/28 00:39:34 peter Exp $ + * $DragonFly: src/sys/boot/arc/include/Attic/libarc.h,v 1.3 2003/11/10 06:08:30 dillon Exp $ */ /* diff --git a/sys/boot/arc/lib/Makefile b/sys/boot/arc/lib/Makefile index 529d1771c2..209e763f17 100644 --- a/sys/boot/arc/lib/Makefile +++ b/sys/boot/arc/lib/Makefile @@ -1,9 +1,10 @@ -# $FreeBSD: src/sys/boot/arc/lib/Makefile,v 1.4.2.1 2002/07/19 18:46:28 ru Exp $ -# $DragonFly: src/sys/boot/arc/lib/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/arc/lib/Makefile,v 1.9 2002/05/13 10:53:24 ru Exp $ +# $DragonFly: src/sys/boot/arc/lib/Attic/Makefile,v 1.3 2003/11/10 06:08:31 dillon Exp $ LIB= arc INTERNALLIB= true +CFLAGS+= -ffreestanding .PATH: ${.CURDIR}/arch/${MACHINE_ARCH} # XXX hack to pick up stand.h LIBSTANDDIR= ${.CURDIR}/../../../../lib/libstand diff --git a/sys/boot/arc/lib/abort.c b/sys/boot/arc/lib/abort.c index 62d2d3c3f5..2672abcde7 100644 --- a/sys/boot/arc/lib/abort.c +++ b/sys/boot/arc/lib/abort.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/abort.c,v 1.2 1999/08/28 00:39:35 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/abort.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/lib/Attic/abort.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/arc/lib/arcconsole.c b/sys/boot/arc/lib/arcconsole.c index 93fb969b03..fb2b59c83d 100644 --- a/sys/boot/arc/lib/arcconsole.c +++ b/sys/boot/arc/lib/arcconsole.c @@ -1,6 +1,8 @@ -/* $FreeBSD: src/sys/boot/arc/lib/arcconsole.c,v 1.2 1999/08/28 00:39:36 peter Exp $ */ -/* $DragonFly: src/sys/boot/arc/lib/Attic/arcconsole.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ -/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */ +/* + * $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ + * $FreeBSD: src/sys/boot/arc/lib/arcconsole.c,v 1.2 1999/08/28 00:39:36 peter Exp $ + * $DragonFly: src/sys/boot/arc/lib/Attic/arcconsole.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ + */ /* * Mach Operating System diff --git a/sys/boot/arc/lib/arcdisk.c b/sys/boot/arc/lib/arcdisk.c index a128ce4904..2c792d50ab 100644 --- a/sys/boot/arc/lib/arcdisk.c +++ b/sys/boot/arc/lib/arcdisk.c @@ -24,8 +24,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/arc/lib/arcdisk.c,v 1.3.2.1 2001/01/05 17:37:51 mjacob Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/arcdisk.c,v 1.3 2003/11/09 02:22:30 dillon Exp $ + * $FreeBSD$ + * $DragonFly: src/sys/boot/arc/lib/Attic/arcdisk.c,v 1.4 2003/11/10 06:08:31 dillon Exp $ */ /* @@ -40,8 +40,6 @@ #include -#include -#include #include @@ -150,11 +148,11 @@ bd_open(struct open_file *f, ...) int error; int unit; u_int32_t fd; - __va_list ap; + va_list ap; - __va_start(ap, f); - dev = __va_arg(ap, struct arc_devdesc *); - __va_end(ap); + va_start(ap, f); + dev = va_arg(ap, struct arc_devdesc *); + va_end(ap); unit = dev->d_kind.arcdisk.unit; if (unit >= nbdinfo) { diff --git a/sys/boot/arc/lib/arch/alpha/copy.c b/sys/boot/arc/lib/arch/alpha/copy.c index 2e471f8927..7aa4d90bb3 100644 --- a/sys/boot/arc/lib/arch/alpha/copy.c +++ b/sys/boot/arc/lib/arch/alpha/copy.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/arch/alpha/copy.c,v 1.2 1999/08/28 00:39:40 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/copy.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/copy.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* * MD primitives supporting placement of module data diff --git a/sys/boot/arc/lib/arch/alpha/rpb.c b/sys/boot/arc/lib/arch/alpha/rpb.c index e9ad2fa4ac..d86b0baa56 100644 --- a/sys/boot/arc/lib/arch/alpha/rpb.c +++ b/sys/boot/arc/lib/arch/alpha/rpb.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/arch/alpha/rpb.c,v 1.2 1999/08/28 00:39:40 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/rpb.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/rpb.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/arc/lib/arch/alpha/setjmp.S b/sys/boot/arc/lib/arch/alpha/setjmp.S index 7b3e4ce782..a2292141fb 100644 --- a/sys/boot/arc/lib/arch/alpha/setjmp.S +++ b/sys/boot/arc/lib/arch/alpha/setjmp.S @@ -1,5 +1,3 @@ -/* $FreeBSD: src/sys/boot/arc/lib/arch/alpha/setjmp.S,v 1.2 1999/08/28 00:39:40 peter Exp $ */ -/* $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/setjmp.S,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ /* * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. * All rights reserved. @@ -25,6 +23,9 @@ * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. + * + * $FreeBSD: src/sys/boot/arc/lib/arch/alpha/setjmp.S,v 1.2 1999/08/28 00:39:40 peter Exp $ + * $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/setjmp.S,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/arc/lib/arch/alpha/start.S b/sys/boot/arc/lib/arch/alpha/start.S index c69bdca4c8..534f6b8ada 100644 --- a/sys/boot/arc/lib/arch/alpha/start.S +++ b/sys/boot/arc/lib/arch/alpha/start.S @@ -24,8 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/arch/alpha/start.S,v 1.2 1999/08/28 00:39:41 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/start.S,v 1.2 2003/06/17 04:28:16 dillon Exp $ - * + * $DragonFly: src/sys/boot/arc/lib/arch/alpha/Attic/start.S,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* diff --git a/sys/boot/arc/lib/bootinfo.c b/sys/boot/arc/lib/bootinfo.c index 5213e8c3d2..fd535f5a6a 100644 --- a/sys/boot/arc/lib/bootinfo.c +++ b/sys/boot/arc/lib/bootinfo.c @@ -23,14 +23,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/arc/lib/bootinfo.c,v 1.2.2.1 2001/03/04 04:40:41 obrien Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/bootinfo.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD$ + * $DragonFly: src/sys/boot/arc/lib/Attic/bootinfo.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include #include #include -#include #include #include #include @@ -122,17 +121,17 @@ bi_copyenv(vm_offset_t addr) vm_offset_t bi_copymodules(vm_offset_t addr) { - struct loaded_module *mp; - struct module_metadata *md; + struct preloaded_file *fp; + struct file_metadata *md; /* start with the first module on the list, should be the kernel */ - for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) { + for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - MOD_NAME(addr, mp->m_name); /* this field must come first */ - MOD_TYPE(addr, mp->m_type); - MOD_ADDR(addr, mp->m_addr); - MOD_SIZE(addr, mp->m_size); - for (md = mp->m_metadata; md != NULL; md = md->md_next) + MOD_NAME(addr, fp->f_name); /* this field must come first */ + MOD_TYPE(addr, fp->f_type); + MOD_ADDR(addr, fp->f_addr); + MOD_SIZE(addr, fp->f_size); + for (md = fp->f_metadata; md != NULL; md = md->md_next) if (!(md->md_type & MODINFOMD_NOCOPY)) MOD_METADATA(addr, md); } @@ -148,18 +147,18 @@ bi_copymodules(vm_offset_t addr) */ int bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save, - struct loaded_module *mp) + struct preloaded_file *fp) { - struct loaded_module *xp; + struct preloaded_file *xp; vm_offset_t addr, bootinfo_addr; u_int pad; vm_offset_t ssym, esym; - struct module_metadata *md; + struct file_metadata *md; ssym = esym = 0; - if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL) + if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL) ssym = *((vm_offset_t *)&(md->md_data)); - if ((md = mod_findmetadata(mp, MODINFOMD_ESYM)) != NULL) + if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL) esym = *((vm_offset_t *)&(md->md_data)); if (ssym == 0 || esym == 0) ssym = esym = 0; /* sanity */ @@ -169,9 +168,9 @@ bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save, /* find the last module in the chain */ addr = 0; - for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) { - if (addr < (xp->m_addr + xp->m_size)) - addr = xp->m_addr + xp->m_size; + for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { + if (addr < (xp->f_addr + xp->f_size)) + addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ pad = (u_int)addr & PAGE_MASK; diff --git a/sys/boot/arc/lib/delay.c b/sys/boot/arc/lib/delay.c index 7e4b229072..4a0c830370 100644 --- a/sys/boot/arc/lib/delay.c +++ b/sys/boot/arc/lib/delay.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/delay.c,v 1.2 1999/08/28 00:39:37 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/delay.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/lib/Attic/delay.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/arc/lib/devicename.c b/sys/boot/arc/lib/devicename.c index fea257d709..c7855258af 100644 --- a/sys/boot/arc/lib/devicename.c +++ b/sys/boot/arc/lib/devicename.c @@ -23,13 +23,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/arc/lib/devicename.c,v 1.2 1999/08/28 00:39:38 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/devicename.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD$ + * $DragonFly: src/sys/boot/arc/lib/Attic/devicename.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include #include -#include #include "bootstrap.h" #include "libarc.h" diff --git a/sys/boot/arc/lib/elf_freebsd.c b/sys/boot/arc/lib/elf_freebsd.c index f856c64fbc..19ca08d46d 100644 --- a/sys/boot/arc/lib/elf_freebsd.c +++ b/sys/boot/arc/lib/elf_freebsd.c @@ -1,6 +1,8 @@ -/* $FreeBSD: src/sys/boot/arc/lib/elf_freebsd.c,v 1.2 1999/08/28 00:39:38 peter Exp $ */ -/* $DragonFly: src/sys/boot/arc/lib/Attic/elf_freebsd.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ -/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */ +/* + * $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ + * $FreeBSD: src/sys/boot/arc/lib/elf_freebsd.c,v 1.4 2003/05/01 03:56:29 peter Exp $ + * $DragonFly: src/sys/boot/arc/lib/Attic/elf_freebsd.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ + */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -91,37 +93,37 @@ #define _KERNEL -static int elf_exec(struct loaded_module *amp); +static int elf64_exec(struct preloaded_file *amp); int bi_load(struct bootinfo_v1 *, vm_offset_t *, - struct loaded_module *); + struct preloaded_file *); -struct module_format alpha_elf = { elf_loadmodule, elf_exec }; +struct file_format alpha_elf = { elf64_loadfile, elf64_exec }; vm_offset_t ffp_save, ptbr_save; static int -elf_exec(struct loaded_module *mp) +elf64_exec(struct preloaded_file *fp) { #if 0 static struct bootinfo_v1 bootinfo_v1; - struct module_metadata *md; + struct file_metadata *md; Elf_Ehdr *hdr; int err; - if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL) + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); /* XXX actually EFUCKUP */ hdr = (Elf_Ehdr *)&(md->md_data); /* XXX ffp_save does not appear to be used in the kernel.. */ bzero(&bootinfo_v1, sizeof(bootinfo_v1)); - err = bi_load(&bootinfo_v1, &ffp_save, mp); + err = bi_load(&bootinfo_v1, &ffp_save, fp); if (err) return(err); /* * Fill in the bootinfo for the kernel. */ - strncpy(bootinfo_v1.booted_kernel, mp->m_name, + strncpy(bootinfo_v1.booted_kernel, fp->f_name, sizeof(bootinfo_v1.booted_kernel)); prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags, sizeof(bootinfo_v1.boot_flags)); @@ -131,7 +133,7 @@ elf_exec(struct loaded_module *mp) bootinfo_v1.cnputc = NULL; bootinfo_v1.cnpollc = NULL; - printf("Entering %s at 0x%lx...\n", mp->m_name, hdr->e_entry); + printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); exit(0); closeall(); alpha_pal_imb(); diff --git a/sys/boot/arc/lib/module.c b/sys/boot/arc/lib/module.c index 50c9c14335..686efce4eb 100644 --- a/sys/boot/arc/lib/module.c +++ b/sys/boot/arc/lib/module.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/module.c,v 1.2 1999/08/28 00:39:38 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/module.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/lib/Attic/module.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* diff --git a/sys/boot/arc/lib/prom.c b/sys/boot/arc/lib/prom.c index cfb46da098..4b22c52d72 100644 --- a/sys/boot/arc/lib/prom.c +++ b/sys/boot/arc/lib/prom.c @@ -24,8 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/prom.c,v 1.2 1999/08/28 00:39:38 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/prom.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ - * + * $DragonFly: src/sys/boot/arc/lib/Attic/prom.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #define PROM_E_BOOTED_DEV "XXX1" diff --git a/sys/boot/arc/lib/setjmperr.c b/sys/boot/arc/lib/setjmperr.c index dd332cfbdd..59c2bfa30a 100644 --- a/sys/boot/arc/lib/setjmperr.c +++ b/sys/boot/arc/lib/setjmperr.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/setjmperr.c,v 1.2 1999/08/28 00:39:39 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/setjmperr.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/lib/Attic/setjmperr.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/arc/lib/time.c b/sys/boot/arc/lib/time.c index 56c48f7875..b3b4907d81 100644 --- a/sys/boot/arc/lib/time.c +++ b/sys/boot/arc/lib/time.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/lib/time.c,v 1.2 1999/08/28 00:39:39 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/time.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/lib/Attic/time.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/arc/loader/Makefile b/sys/boot/arc/loader/Makefile index 11210875ab..0c3c2c0e95 100644 --- a/sys/boot/arc/loader/Makefile +++ b/sys/boot/arc/loader/Makefile @@ -1,6 +1,6 @@ # $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $ -# $FreeBSD: src/sys/boot/arc/loader/Makefile,v 1.4.2.1 2000/08/04 08:31:08 obrien Exp $ -# $DragonFly: src/sys/boot/arc/loader/Attic/Makefile,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/arc/loader/Makefile,v 1.7 2002/05/10 09:26:30 obrien Exp $ +# $DragonFly: src/sys/boot/arc/loader/Attic/Makefile,v 1.3 2003/11/10 06:08:31 dillon Exp $ BASE= loader PROG= ${BASE}.exe @@ -15,7 +15,7 @@ SRCS+= main.c conf.c # Always add MI sources .PATH: ${.CURDIR}/../../common .include <${.CURDIR}/../../common/Makefile.inc> -CFLAGS+= -mno-fp-regs +CFLAGS+= -ffreestanding -mno-fp-regs CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR} CFLAGS+= -I${.CURDIR}/../../.. -I. CFLAGS+= -DLOADER @@ -43,9 +43,9 @@ vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${BASE}.exe: ${BASE}.sym ${BASE}.help elf2exe ${BASE}.sym ${BASE}.exe -${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBARC} ${CRT} vers.o setdef0.o setdef1.o +${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBARC} ${CRT} vers.o ${LD} -o ${BASE}.sym -M -N -Ttext ${LOAD_ADDRESS} \ - ${CRT} setdef0.o ${OBJS} setdef1.o vers.o -L${DESTDIR}${LIBDIR} \ + ${CRT} ${OBJS} vers.o -L${DESTDIR}${LIBDIR} \ ${LIBSTAND} ${LIBARC} ${LIBSTAND} >${.OBJDIR}/${BASE}.list ${BASE}.help: help.common help.alpha @@ -64,18 +64,9 @@ beforeinstall: start.o: ${.CURDIR}/../lib/arch/${MACHINE_ARCH}/start.S ${CC} -c ${CFLAGS} $< -setdef0.o: setdefs.h - -setdef1.o: setdefs.h - machine: ln -sf ${.CURDIR}/../../../alpha/include machine .include -.ORDER: setdefs.h setdef0.c setdef1.c -setdefs.h setdef0.c setdef1.c: ${OBJS} - @echo Generating linker sets - @gensetdefs ${OBJS} - beforedepend ${OBJS}: machine diff --git a/sys/boot/arc/loader/conf.c b/sys/boot/arc/loader/conf.c index 32df1e780c..7e7e65bf80 100644 --- a/sys/boot/arc/loader/conf.c +++ b/sys/boot/arc/loader/conf.c @@ -1,7 +1,7 @@ /* - * $FreeBSD: src/sys/boot/arc/loader/conf.c,v 1.2 1999/08/28 00:39:42 peter Exp $ - * $DragonFly: src/sys/boot/arc/loader/Attic/conf.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ * From $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ + * $FreeBSD: src/sys/boot/arc/loader/conf.c,v 1.4 2002/12/19 19:34:58 jake Exp $ + * $DragonFly: src/sys/boot/arc/loader/Attic/conf.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* @@ -56,7 +56,7 @@ struct devsw *devsw[] = { struct fs_ops *file_system[] = { &ufs_fsops, - &zipfs_fsops, + &gzipfs_fsops, NULL }; @@ -65,9 +65,9 @@ struct fs_ops *file_system[] = { * Sort formats so that those that can detect based on arguments * rather than reading the file go first. */ -extern struct module_format alpha_elf; +extern struct file_format alpha_elf; -struct module_format *module_formats[] = { +struct file_format *file_formats[] = { &alpha_elf, NULL }; diff --git a/sys/boot/arc/loader/main.c b/sys/boot/arc/loader/main.c index 456bb9b0a5..b85a3857b7 100644 --- a/sys/boot/arc/loader/main.c +++ b/sys/boot/arc/loader/main.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/arc/loader/main.c,v 1.3 1999/08/28 00:39:42 peter Exp $ - * $DragonFly: src/sys/boot/arc/loader/Attic/main.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/arc/loader/Attic/main.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ diff --git a/sys/boot/arc/loader/version b/sys/boot/arc/loader/version index b253d90c02..484c9b5a03 100644 --- a/sys/boot/arc/loader/version +++ b/sys/boot/arc/loader/version @@ -1,5 +1,5 @@ $FreeBSD: src/sys/boot/arc/loader/version,v 1.2 1999/08/28 00:39:43 peter Exp $ -$DragonFly: src/sys/boot/arc/loader/Attic/version,v 1.2 2003/06/17 04:28:16 dillon Exp $ +$DragonFly: src/sys/boot/arc/loader/Attic/version,v 1.3 2003/11/10 06:08:31 dillon Exp $ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important. Make sure the current version number is on line 6. diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc index 94a3a576ab..48747e79b9 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/common/Makefile.inc @@ -1,10 +1,24 @@ -# $FreeBSD: src/sys/boot/common/Makefile.inc,v 1.9.2.2 2001/04/25 11:24:01 ru Exp $ -# $DragonFly: src/sys/boot/common/Makefile.inc,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/common/Makefile.inc,v 1.16 2003/06/26 03:51:57 peter Exp $ +# $DragonFly: src/sys/boot/common/Makefile.inc,v 1.3 2003/11/10 06:08:31 dillon Exp $ SRCS+= bcache.c boot.c commands.c console.c devopen.c interp.c -SRCS+= interp_backslash.c interp_parse.c load_aout.c load_elf.c ls.c misc.c +SRCS+= interp_backslash.c interp_parse.c ls.c misc.c SRCS+= module.c panic.c +.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" +SRCS+= load_elf32.c load_elf64.c +.endif +.if ${MACHINE_ARCH} == "powerpc" +SRCS+= load_elf32.c +.endif +.if ${MACHINE_ARCH} == "sparc64" || ${MACHINE_ARCH} == "ia64" || ${MACHINE_ARCH} == "alpha" +SRCS+= load_elf64.c +.endif + +.if defined(LOADER_NET_SUPPORT) +SRCS+= dev_net.c +.endif + # Machine-independant ISA PnP .if HAVE_ISABUS SRCS+= isapnp.c @@ -21,4 +35,3 @@ MAN+= ../forth/loader.4th.8 .endif MAN+= loader.8 - diff --git a/sys/boot/common/bcache.c b/sys/boot/common/bcache.c index 20d3ba59fe..3d220ca2c2 100644 --- a/sys/boot/common/bcache.c +++ b/sys/boot/common/bcache.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/bcache.c,v 1.6.2.2 2000/12/28 13:12:31 ps Exp $ - * $DragonFly: src/sys/boot/common/bcache.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/bcache.c,v 1.12 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/bcache.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* @@ -41,7 +41,7 @@ #ifdef BCACHE_DEBUG #define BCACHE_TIMEOUT 10 -# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args) +# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args) #else #define BCACHE_TIMEOUT 2 # define DEBUG(fmt, args...) @@ -64,6 +64,7 @@ static u_int bcache_hits, bcache_misses, bcache_ops, bcache_bypasses; static u_int bcache_flushes; static u_int bcache_bcount; +static void bcache_invalidate(daddr_t blkno); static void bcache_insert(caddr_t buf, daddr_t blkno); static int bcache_lookup(caddr_t buf, daddr_t blkno); @@ -117,38 +118,52 @@ bcache_flush(void) } } -/* - * Handle a transfer request; fill in parts of the request that can - * be satisfied by the cache, use the supplied strategy routine to do - * device I/O and then use the I/O results to populate the cache. - * - * Requests larger than 1/2 the cache size will be bypassed and go - * directly to the disk. XXX tune this. +/* + * Handle a write request; write directly to the disk, and populate the + * cache with the new values. */ -int -bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, +static int +write_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { - static int bcache_unit = -1; struct bcache_devdata *dd = (struct bcache_devdata *)devdata; - int p_size, result; - daddr_t p_blk, i, j, nblk; - caddr_t p_buf; + daddr_t i, nblk; + int err; - bcache_ops++; + nblk = size / bcache_blksize; - if(bcache_unit != unit) { - bcache_flush(); - bcache_unit = unit; + /* Invalidate the blocks being written */ + for (i = 0; i < nblk; i++) { + bcache_invalidate(blk + i); } - /* bypass large requests, or when the cache is inactive */ - if ((bcache_data == NULL) || ((size * 2 / bcache_blksize) > bcache_nblks)) { - DEBUG("bypass %d from %d", size / bcache_blksize, blk); - bcache_bypasses++; - return(dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); + /* Write the blocks */ + err = dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize); + + /* Populate the block cache with the new data */ + if (err == 0) { + for (i = 0; i < nblk; i++) { + bcache_insert(buf + (i * bcache_blksize),blk + i); + } } + return err; +} + +/* + * Handle a read request; fill in parts of the request that can + * be satisfied by the cache, use the supplied strategy routine to do + * device I/O and then use the I/O results to populate the cache. + */ +static int +read_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, + char *buf, size_t *rsize) +{ + struct bcache_devdata *dd = (struct bcache_devdata *)devdata; + int p_size, result; + daddr_t p_blk, i, j, nblk; + caddr_t p_buf; + nblk = size / bcache_blksize; result = 0; @@ -202,6 +217,40 @@ bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, return(result); } +/* + * Requests larger than 1/2 the cache size will be bypassed and go + * directly to the disk. XXX tune this. + */ +int +bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size, + char *buf, size_t *rsize) +{ + static int bcache_unit = -1; + struct bcache_devdata *dd = (struct bcache_devdata *)devdata; + + bcache_ops++; + + if(bcache_unit != unit) { + bcache_flush(); + bcache_unit = unit; + } + + /* bypass large requests, or when the cache is inactive */ + if ((bcache_data == NULL) || ((size * 2 / bcache_blksize) > bcache_nblks)) { + DEBUG("bypass %d from %d", size / bcache_blksize, blk); + bcache_bypasses++; + return(dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize)); + } + + switch (rw) { + case F_READ: + return read_strategy(devdata, unit, rw, blk, size, buf, rsize); + case F_WRITE: + return write_strategy(devdata, unit, rw, blk, size, buf, rsize); + } + return -1; +} + /* * Insert a block into the cache. Retire the oldest block to do so, if required. @@ -262,6 +311,24 @@ bcache_lookup(caddr_t buf, daddr_t blkno) return(ENOENT); } +/* + * Invalidate a block from the cache. + */ +static void +bcache_invalidate(daddr_t blkno) +{ + u_int i; + + for (i = 0; i < bcache_nblks; i++) { + if (bcache_ctl[i].bc_blkno == blkno) { + bcache_ctl[i].bc_count = -1; + bcache_ctl[i].bc_blkno = -1; + DEBUG("invalidate blk %d", blkno); + break; + } + } +} + COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache); static int diff --git a/sys/boot/common/boot.c b/sys/boot/common/boot.c index 50d1cfea75..4562f61d9e 100644 --- a/sys/boot/common/boot.c +++ b/sys/boot/common/boot.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/boot.c,v 1.15.2.5 2000/12/28 13:12:33 ps Exp $ - * $DragonFly: src/sys/boot/common/boot.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/boot.c,v 1.29 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/boot.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* @@ -37,9 +37,10 @@ #include "bootstrap.h" static char *getbootfile(int try); +static int loadakernel(int try, int argc, char* argv[]); /* List of kernel names to try (may be overwritten by boot.config) XXX should move from here? */ -static const char *default_bootfiles = "kernel;kernel.old"; +static const char *default_bootfiles = "kernel"; static int autoboot_tried; @@ -51,9 +52,7 @@ COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot); static int command_boot(int argc, char *argv[]) { - struct loaded_module *km; - char *cp; - int try; + struct preloaded_file *fp; /* * See if the user has specified an explicit kernel to boot. @@ -61,13 +60,13 @@ command_boot(int argc, char *argv[]) if ((argc > 1) && (argv[1][0] != '-')) { /* XXX maybe we should discard everything and start again? */ - if (mod_findmodule(NULL, NULL) != NULL) { + if (file_findfile(NULL, NULL) != NULL) { sprintf(command_errbuf, "can't boot '%s', kernel module already loaded", argv[1]); return(CMD_ERROR); } /* find/load the kernel module */ - if (mod_load(argv[1], argc - 2, argv + 2) != 0) + if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0) return(CMD_ERROR); /* we have consumed all arguments */ argc = 1; @@ -76,22 +75,15 @@ command_boot(int argc, char *argv[]) /* * See if there is a kernel module already loaded */ - if (mod_findmodule(NULL, NULL) == NULL) { - for (try = 0; (cp = getbootfile(try)) != NULL; try++) { - if (mod_load(cp, argc - 1, argv + 1) != 0) { - printf("can't load '%s'\n", cp); - } else { - /* we have consumed all arguments */ - argc = 1; - break; - } - } - } + if (file_findfile(NULL, NULL) == NULL) + if (loadakernel(0, argc - 1, argv + 1)) + /* we have consumed all arguments */ + argc = 1; /* * Loaded anything yet? */ - if ((km = mod_findmodule(NULL, NULL)) == NULL) { + if ((fp = file_findfile(NULL, NULL)) == NULL) { command_errmsg = "no bootable kernel"; return(CMD_ERROR); } @@ -101,9 +93,9 @@ command_boot(int argc, char *argv[]) * XXX should we merge arguments? Hard to DWIM. */ if (argc > 1) { - if (km->m_args != NULL) - free(km->m_args); - km->m_args = unargv(argc - 1, argv + 1); + if (fp->f_args != NULL) + free(fp->f_args); + fp->f_args = unargv(argc - 1, argv + 1); } /* Hook for platform-specific autoloading of modules */ @@ -111,7 +103,7 @@ command_boot(int argc, char *argv[]) return(CMD_ERROR); /* Call the exec handler from the loader matching the kernel */ - module_formats[km->m_loader]->l_exec(km); + file_formats[fp->f_loader]->l_exec(fp); return(CMD_ERROR); } @@ -169,6 +161,7 @@ autoboot(int timeout, char *prompt) time_t when, otime, ntime; int c, yes; char *argv[2], *cp, *ep; + char *kernelname; autoboot_tried = 1; @@ -183,11 +176,21 @@ autoboot(int timeout, char *prompt) if (timeout == -1) /* all else fails */ timeout = 10; + kernelname = getenv("kernelname"); + if (kernelname == NULL) { + argv[0] = NULL; + loadakernel(0, 0, argv); + kernelname = getenv("kernelname"); + if (kernelname == NULL) { + command_errmsg = "no valid kernel found"; + return(CMD_ERROR); + } + } + otime = time(NULL); when = otime + timeout; /* when to boot */ yes = 0; - /* XXX could try to work out what we might boot */ printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt); for (;;) { @@ -202,15 +205,16 @@ autoboot(int timeout, char *prompt) yes = 1; break; } + if (ntime != otime) { printf("\rBooting [%s] in %d second%s... ", - getbootfile(0), (int)(when - ntime), + kernelname, (int)(when - ntime), (when-ntime)==1?"":"s"); otime = ntime; } } if (yes) - printf("\rBooting [%s]... ", getbootfile(0)); + printf("\rBooting [%s]... ", kernelname); putchar('\n'); if (yes) { argv[0] = "boot"; @@ -227,7 +231,7 @@ static char * getbootfile(int try) { static char *name = NULL; - char *spec, *ep; + const char *spec, *ep; size_t len; /* we use dynamic storage */ @@ -333,3 +337,17 @@ getrootmount(char *rootdev) close(fd); return(error); } + +static int +loadakernel(int try, int argc, char* argv[]) +{ + char *cp; + + for (try = 0; (cp = getbootfile(try)) != NULL; try++) + if (mod_loadkld(cp, argc - 1, argv + 1) != 0) + printf("can't load '%s'\n", cp); + else + return 1; + return 0; +} + diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h index 8eb184b3b9..fb76bb3183 100644 --- a/sys/boot/common/bootstrap.h +++ b/sys/boot/common/bootstrap.h @@ -23,12 +23,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/bootstrap.h,v 1.24.2.4 2001/12/21 22:19:13 jhb Exp $ - * $DragonFly: src/sys/boot/common/bootstrap.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/bootstrap.h,v 1.38 2003/05/01 03:56:29 peter Exp $ + * $DragonFly: src/sys/boot/common/bootstrap.h,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include #include +#include /* * Generic device specifier; architecture-dependant @@ -140,6 +141,10 @@ struct pnpinfo STAILQ_ENTRY(pnpinfo) pi_link; }; +STAILQ_HEAD(pnpinfo_stql, pnpinfo); + +extern struct pnpinfo_stql pnp_devices; + extern struct pnphandler *pnphandlers[]; /* provided by MD code */ void pnp_addident(struct pnpinfo *pi, char *ident); @@ -156,103 +161,79 @@ char *pnp_eisaformat(u_int8_t *data); extern int isapnp_readport; /* - * Module metadata header. + * Preloaded file metadata header. * * Metadata are allocated on our heap, and copied into kernel space * before executing the kernel. */ -struct module_metadata +struct file_metadata { size_t md_size; u_int16_t md_type; - struct module_metadata *md_next; - char md_data[0]; /* data are immediately appended */ + struct file_metadata *md_next; + char md_data[1]; /* data are immediately appended */ +}; + +struct preloaded_file; +struct mod_depend; + +struct kernel_module +{ + char *m_name; /* module name */ + int m_version; /* module version */ +/* char *m_args;*/ /* arguments for the module */ + struct preloaded_file *m_fp; + struct kernel_module *m_next; }; /* - * Loaded module information. + * Preloaded file information. Depending on type, file can contain + * additional units called 'modules'. * - * At least one module (the kernel) must be loaded in order to boot. + * At least one file (the kernel) must be loaded in order to boot. * The kernel is always loaded first. * * String fields (m_name, m_type) should be dynamically allocated. */ -struct loaded_module +struct preloaded_file { - char *m_name; /* module name */ - char *m_type; /* verbose module type, eg 'ELF kernel', 'pnptable', etc. */ - char *m_args; /* arguments for the module */ - struct module_metadata *m_metadata; /* metadata that will be placed in the module directory */ - int m_loader; /* index of the loader that read the file */ - vm_offset_t m_addr; /* load address */ - size_t m_size; /* module size */ - struct loaded_module *m_next; /* next module */ + char *f_name; /* file name */ + char *f_type; /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */ + char *f_args; /* arguments for the file */ + struct file_metadata *f_metadata; /* metadata that will be placed in the module directory */ + int f_loader; /* index of the loader that read the file */ + vm_offset_t f_addr; /* load address */ + size_t f_size; /* file size */ + struct kernel_module *f_modules; /* list of modules if any */ + struct preloaded_file *f_next; /* next file */ }; -struct module_format +struct file_format { /* Load function must return EFTYPE if it can't handle the module supplied */ - int (* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result); + int (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result); /* Only a loader that will load a kernel (first module) should have an exec handler */ - int (* l_exec)(struct loaded_module *mp); + int (* l_exec)(struct preloaded_file *mp); }; -extern struct module_format *module_formats[]; /* supplied by consumer */ -extern struct loaded_module *loaded_modules; -extern int mod_load(char *name, int argc, char *argv[]); -extern int mod_loadobj(char *type, char *name); -extern struct loaded_module *mod_findmodule(char *name, char *type); -extern void mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p); -extern struct module_metadata *mod_findmetadata(struct loaded_module *mp, int type); -extern void mod_discard(struct loaded_module *mp); -extern struct loaded_module *mod_allocmodule(void); - -/* MI module loaders */ -extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); -extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp); -extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); - -#ifndef NEW_LINKER_SET -#include - -/* XXX just for conversion's sake, until we move to the new linker set code */ - -#define SET_FOREACH(pvar, set) \ - for ((char*) pvar = set.ls_items; \ - (char*) pvar < (char*) &set.ls_items[set.ls_length]; \ - pvar++) -#else /* NEW_LINKER_SET */ +extern struct file_format *file_formats[]; /* supplied by consumer */ +extern struct preloaded_file *preloaded_files; -/* - * Private macros, not to be used outside this header file. - */ -#define __MAKE_SET(set, sym) \ - static void *__CONCAT(__setentry,__LINE__) \ - __attribute__((__section__("set_" #set),__unused__)) = &sym -#define __SET_BEGIN(set) \ - ({ extern void *__CONCAT(__start_set_,set); \ - &__CONCAT(__start_set_,set); }) -#define __SET_END(set) \ - ({ extern void *__CONCAT(__stop_set_,set); \ - &__CONCAT(__stop_set_,set); }) +int mod_load(char *name, struct mod_depend *verinfo, int argc, char *argv[]); +int mod_loadkld(const char *name, int argc, char *argv[]); -/* - * Public macros. - */ +struct preloaded_file *file_alloc(void); +struct preloaded_file *file_findfile(char *name, char *type); +struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type); +void file_discard(struct preloaded_file *fp); +void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p); +int file_addmodule(struct preloaded_file *fp, char *modname, int version, + struct kernel_module **newmp); -/* Add an entry to a set. */ -#define DATA_SET(set, sym) __MAKE_SET(set, sym) -/* - * Iterate over all the elements of a set. - * - * Sets always contain addresses of things, and "pvar" points to words - * containing those addresses. Thus is must be declared as "type **pvar", - * and the address of each set item is obtained inside the loop by "*pvar". - */ -#define SET_FOREACH(pvar, set) \ - for (pvar = (__typeof__(pvar))__SET_BEGIN(set); \ - pvar < (__typeof__(pvar))__SET_END(set); pvar++) +/* MI module loaders */ +#ifdef __elfN +int __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result); #endif /* @@ -270,7 +251,7 @@ struct bootblk_command static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \ DATA_SET(Xcommand_set, _cmd_ ## tag) -extern struct linker_set Xcommand_set; +SET_DECLARE(Xcommand_set, struct bootblk_command); /* * The intention of the architecture switch is to provide a convenient @@ -303,3 +284,5 @@ extern struct arch_switch archsw; void delay(int delay); void dev_cleanup(void); + +time_t time(time_t *tloc); diff --git a/sys/boot/common/commands.c b/sys/boot/common/commands.c index 5ff5faa66d..68ac31bb6a 100644 --- a/sys/boot/common/commands.c +++ b/sys/boot/common/commands.c @@ -23,13 +23,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/commands.c,v 1.13.2.3 2001/03/05 02:27:01 obrien Exp $ - * $DragonFly: src/sys/boot/common/commands.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/commands.c,v 1.19 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/commands.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include #include -#include #include "bootstrap.h" @@ -470,7 +469,7 @@ command_lsdev(int argc, char *argv[]) pager_open(); for (i = 0; devsw[i] != NULL; i++) { if (devsw[i]->dv_print != NULL){ - sprintf(line, "%s @ %p\n", devsw[i]->dv_name, devsw[i]->dv_print); + sprintf(line, "%s devices:\n", devsw[i]->dv_name); if (pager_output(line)) break; devsw[i]->dv_print(verbose); diff --git a/sys/boot/common/console.c b/sys/boot/common/console.c index b2957f16c6..c64e1ee453 100644 --- a/sys/boot/common/console.c +++ b/sys/boot/common/console.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/console.c,v 1.5 1999/08/28 00:39:46 peter Exp $ - * $DragonFly: src/sys/boot/common/console.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/console.c,v 1.6 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/console.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/common/dev_net.c b/sys/boot/common/dev_net.c index 3559417bed..728204a3df 100644 --- a/sys/boot/common/dev_net.c +++ b/sys/boot/common/dev_net.c @@ -1,7 +1,5 @@ /* - * $FreeBSD: src/sys/boot/common/dev_net.c,v 1.6.2.5 2001/03/04 04:44:42 obrien Exp $ - * $DragonFly: src/sys/boot/common/dev_net.c,v 1.3 2003/11/09 02:22:33 dillon Exp $ - * From: $NetBSD: dev_net.c,v 1.12 1997/12/10 20:38:37 gwr Exp $ + * $NetBSD: dev_net.c,v 1.12 1997/12/10 20:38:37 gwr Exp $ */ /*- @@ -38,9 +36,12 @@ * 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. + * + * $FreeBSD: src/sys/boot/common/dev_net.c,v 1.13 2003/11/03 19:45:05 iedowse Exp $ + * $DragonFly: src/sys/boot/common/dev_net.c,v 1.4 2003/11/10 06:08:31 dillon Exp $ */ -/* +/*- * This module implements a "raw device" interface suitable for * use by the stand-alone I/O library NFS code. This interface * does not support any "block" access, and exists only for the @@ -113,13 +114,13 @@ net_init(void) int net_open(struct open_file *f, ...) { - __va_list args; + va_list args; char *devname; /* Device part of file name (or NULL). */ int error = 0; - __va_start(args, f); - devname = __va_arg(args, char*); - __va_end(args); + va_start(args, f); + devname = va_arg(args, char*); + va_end(args); /* On first open, do netif open, mount, etc. */ if (netdev_opens == 0) { @@ -210,6 +211,7 @@ net_getparams(sock) { char buf[MAXHOSTNAMELEN]; char temp[FNAME_SIZE]; + struct iodesc *d; int i; n_long smask; @@ -268,23 +270,33 @@ net_getparams(sock) return (EIO); } exit: - printf("net_open: server addr: %s\n", inet_ntoa(rootip)); - /* * If present, strip the server's address off of the rootpath * before passing it along. This allows us to be compatible with * the kernel's diskless (BOOTP_NFSROOT) booting conventions */ - - for(i=0; imyea, ":"); + setenv("boot.netif.ip", inet_ntoa(myip), 1); + setenv("boot.netif.netmask", intoa(netmask), 1); + setenv("boot.netif.gateway", inet_ntoa(gateip), 1); + setenv("boot.netif.hwaddr", temp, 1); + setenv("boot.nfsroot.server", inet_ntoa(rootip), 1); + setenv("boot.nfsroot.path", rootpath, 1); + return (0); } diff --git a/sys/boot/common/dev_net.h b/sys/boot/common/dev_net.h index 803d405dea..aa4d8be533 100644 --- a/sys/boot/common/dev_net.h +++ b/sys/boot/common/dev_net.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/common/dev_net.h,v 1.2 1999/08/28 00:39:46 peter Exp $ - * $DragonFly: src/sys/boot/common/dev_net.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/common/dev_net.h,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ extern struct devsw netdev; diff --git a/sys/boot/common/devopen.c b/sys/boot/common/devopen.c index 349034719f..d9e4ce30bc 100644 --- a/sys/boot/common/devopen.c +++ b/sys/boot/common/devopen.c @@ -23,11 +23,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/devopen.c,v 1.3 1999/08/28 00:39:47 peter Exp $ - * $DragonFly: src/sys/boot/common/devopen.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/devopen.c,v 1.4 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/devopen.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ - #include #include diff --git a/sys/boot/common/dinode.h b/sys/boot/common/dinode.h new file mode 100644 index 0000000000..07bde9cc5a --- /dev/null +++ b/sys/boot/common/dinode.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Marshall + * Kirk McKusick and Network Associates Laboratories, the Security + * Research Division of Network Associates, Inc. under DARPA/SPAWAR + * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS + * research program + * + * Copyright (c) 1982, 1989, 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. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * @(#)dinode.h 8.3 (Berkeley) 1/21/94 + * $FreeBSD: src/sys/ufs/ufs/dinode.h,v 1.11 2002/07/16 22:36:00 mckusick Exp $ + * $DragonFly: src/sys/boot/common/dinode.h,v 1.1 2003/11/10 06:08:31 dillon Exp $ + */ + +#ifndef _UFS_UFS_DINODE_H_ +#define _UFS_UFS_DINODE_H_ + +/* + * The root inode is the root of the filesystem. Inode 0 can't be used for + * normal purposes and historically bad blocks were linked to inode 1, thus + * the root inode is 2. (Inode 1 is no longer used for this purpose, however + * numerous dump tapes make this assumption, so we are stuck with it). + */ +#define ROOTINO ((ino_t)2) + +/* + * The Whiteout inode# is a dummy non-zero inode number which will + * never be allocated to a real file. It is used as a place holder + * in the directory entry which has been tagged as a DT_W entry. + * See the comments about ROOTINO above. + */ +#define WINO ((ino_t)1) + +/* + * The size of physical and logical block numbers and time fields in UFS. + */ +typedef int32_t ufs1_daddr_t; +typedef int64_t ufs2_daddr_t; +typedef int64_t ufs_lbn_t; +typedef int64_t ufs_time_t; + +/* File permissions. */ +#define IEXEC 0000100 /* Executable. */ +#define IWRITE 0000200 /* Writeable. */ +#define IREAD 0000400 /* Readable. */ +#define ISVTX 0001000 /* Sticky bit. */ +#define ISGID 0002000 /* Set-gid. */ +#define ISUID 0004000 /* Set-uid. */ + +/* File types. */ +#define IFMT 0170000 /* Mask of file type. */ +#define IFIFO 0010000 /* Named pipe (fifo). */ +#define IFCHR 0020000 /* Character device. */ +#define IFDIR 0040000 /* Directory file. */ +#define IFBLK 0060000 /* Block device. */ +#define IFREG 0100000 /* Regular file. */ +#define IFLNK 0120000 /* Symbolic link. */ +#define IFSOCK 0140000 /* UNIX domain socket. */ +#define IFWHT 0160000 /* Whiteout. */ + +/* + * A dinode contains all the meta-data associated with a UFS2 file. + * This structure defines the on-disk format of a dinode. Since + * this structure describes an on-disk structure, all its fields + * are defined by types with precise widths. + */ + +#define NXADDR 2 /* External addresses in inode. */ +#define NDADDR 12 /* Direct addresses in inode. */ +#define NIADDR 3 /* Indirect addresses in inode. */ + +struct ufs2_dinode { + u_int16_t di_mode; /* 0: IFMT, permissions; see below. */ + int16_t di_nlink; /* 2: File link count. */ + u_int32_t di_uid; /* 4: File owner. */ + u_int32_t di_gid; /* 8: File group. */ + u_int32_t di_blksize; /* 12: Inode blocksize. */ + u_int64_t di_size; /* 16: File byte count. */ + u_int64_t di_blocks; /* 24: Bytes actually held. */ + ufs_time_t di_atime; /* 32: Last access time. */ + ufs_time_t di_mtime; /* 40: Last modified time. */ + ufs_time_t di_ctime; /* 48: Last inode change time. */ + ufs_time_t di_birthtime; /* 56: Inode creation time. */ + int32_t di_mtimensec; /* 64: Last modified time. */ + int32_t di_atimensec; /* 68: Last access time. */ + int32_t di_ctimensec; /* 72: Last inode change time. */ + int32_t di_birthnsec; /* 76: Inode creation time. */ + int32_t di_gen; /* 80: Generation number. */ + u_int32_t di_kernflags; /* 84: Kernel flags. */ + u_int32_t di_flags; /* 88: Status flags (chflags). */ + int32_t di_extsize; /* 92: External attributes block. */ + ufs2_daddr_t di_extb[NXADDR];/* 96: External attributes block. */ + ufs2_daddr_t di_db[NDADDR]; /* 112: Direct disk blocks. */ + ufs2_daddr_t di_ib[NIADDR]; /* 208: Indirect disk blocks. */ + int64_t di_spare[3]; /* 232: Reserved; currently unused */ +}; + +/* + * The di_db fields may be overlaid with other information for + * file types that do not have associated disk storage. Block + * and character devices overlay the first data block with their + * dev_t value. Short symbolic links place their path in the + * di_db area. + */ +#define di_rdev di_db[0] + +/* + * A UFS1 dinode contains all the meta-data associated with a UFS1 file. + * This structure defines the on-disk format of a UFS1 dinode. Since + * this structure describes an on-disk structure, all its fields + * are defined by types with precise widths. + */ +struct ufs1_dinode { + u_int16_t di_mode; /* 0: IFMT, permissions; see below. */ + int16_t di_nlink; /* 2: File link count. */ + union { + u_int16_t oldids[2]; /* 4: Ffs: old user and group ids. */ + } di_u; + u_int64_t di_size; /* 8: File byte count. */ + int32_t di_atime; /* 16: Last access time. */ + int32_t di_atimensec; /* 20: Last access time. */ + int32_t di_mtime; /* 24: Last modified time. */ + int32_t di_mtimensec; /* 28: Last modified time. */ + int32_t di_ctime; /* 32: Last inode change time. */ + int32_t di_ctimensec; /* 36: Last inode change time. */ + ufs1_daddr_t di_db[NDADDR]; /* 40: Direct disk blocks. */ + ufs1_daddr_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */ + u_int32_t di_flags; /* 100: Status flags (chflags). */ + int32_t di_blocks; /* 104: Blocks actually held. */ + int32_t di_gen; /* 108: Generation number. */ + u_int32_t di_uid; /* 112: File owner. */ + u_int32_t di_gid; /* 116: File group. */ + int32_t di_spare[2]; /* 120: Reserved; currently unused */ +}; +#define di_ogid di_u.oldids[1] +#define di_ouid di_u.oldids[0] + +#endif /* _UFS_UFS_DINODE_H_ */ diff --git a/sys/boot/common/fs.h b/sys/boot/common/fs.h new file mode 100644 index 0000000000..0cdfbeb5bf --- /dev/null +++ b/sys/boot/common/fs.h @@ -0,0 +1,604 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * 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. + * + * @(#)fs.h 8.13 (Berkeley) 3/21/95 + * $FreeBSD$ + * $DragonFly: src/sys/boot/common/fs.h,v 1.1 2003/11/10 06:08:31 dillon Exp $ + */ + +#ifndef _UFS_FFS_FS_H_ +#define _UFS_FFS_FS_H_ + +/* + * Each disk drive contains some number of filesystems. + * A filesystem consists of a number of cylinder groups. + * Each cylinder group has inodes and data. + * + * A filesystem is described by its super-block, which in turn + * describes the cylinder groups. The super-block is critical + * data and is replicated in each cylinder group to protect against + * catastrophic loss. This is done at `newfs' time and the critical + * super-block data does not change, so the copies need not be + * referenced further unless disaster strikes. + * + * For filesystem fs, the offsets of the various blocks of interest + * are given in the super block as: + * [fs->fs_sblkno] Super-block + * [fs->fs_cblkno] Cylinder group block + * [fs->fs_iblkno] Inode blocks + * [fs->fs_dblkno] Data blocks + * The beginning of cylinder group cg in fs, is given by + * the ``cgbase(fs, cg)'' macro. + * + * Depending on the architecture and the media, the superblock may + * reside in any one of four places. For tiny media where every block + * counts, it is placed at the very front of the partition. Historically, + * UFS1 placed it 8K from the front to leave room for the disk label and + * a small bootstrap. For UFS2 it got moved to 64K from the front to leave + * room for the disk label and a bigger bootstrap, and for really piggy + * systems we check at 256K from the front if the first three fail. In + * all cases the size of the superblock will be SBLOCKSIZE. All values are + * given in byte-offset form, so they do not imply a sector size. The + * SBLOCKSEARCH specifies the order in which the locations should be searched. + */ +#define SBLOCK_FLOPPY 0 +#define SBLOCK_UFS1 8192 +#define SBLOCK_UFS2 65536 +#define SBLOCK_PIGGY 262144 +#define SBLOCKSIZE 8192 +#define SBLOCKSEARCH \ + { SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 } + +/* + * Max number of fragments per block. This value is NOT tweakable. + */ +#define MAXFRAG 8 + +/* + * Addresses stored in inodes are capable of addressing fragments + * of `blocks'. File system blocks of at most size MAXBSIZE can + * be optionally broken into 2, 4, or 8 pieces, each of which is + * addressable; these pieces may be DEV_BSIZE, or some multiple of + * a DEV_BSIZE unit. + * + * Large files consist of exclusively large data blocks. To avoid + * undue wasted disk space, the last data block of a small file may be + * allocated as only as many fragments of a large block as are + * necessary. The filesystem format retains only a single pointer + * to such a fragment, which is a piece of a single large block that + * has been divided. The size of such a fragment is determinable from + * information in the inode, using the ``blksize(fs, ip, lbn)'' macro. + * + * The filesystem records space availability at the fragment level; + * to determine block availability, aligned fragments are examined. + */ + +/* + * MINBSIZE is the smallest allowable block size. + * In order to insure that it is possible to create files of size + * 2^32 with only two levels of indirection, MINBSIZE is set to 4096. + * MINBSIZE must be big enough to hold a cylinder group block, + * thus changes to (struct cg) must keep its size within MINBSIZE. + * Note that super blocks are always of size SBSIZE, + * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE. + */ +#define MINBSIZE 4096 + +/* + * The path name on which the filesystem is mounted is maintained + * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in + * the super block for this name. + */ +#define MAXMNTLEN 468 + +/* + * The volume name for this filesystem is maintained in fs_volname. + * MAXVOLLEN defines the length of the buffer allocated. + */ +#define MAXVOLLEN 32 + +/* + * There is a 128-byte region in the superblock reserved for in-core + * pointers to summary information. Originally this included an array + * of pointers to blocks of struct csum; now there are just a few + * pointers and the remaining space is padded with fs_ocsp[]. + * + * NOCSPTRS determines the size of this padding. One pointer (fs_csp) + * is taken away to point to a contiguous array of struct csum for + * all cylinder groups; a second (fs_maxcluster) points to an array + * of cluster sizes that is computed as cylinder groups are inspected, + * and the third points to an array that tracks the creation of new + * directories. A fourth pointer, fs_active, is used when creating + * snapshots; it points to a bitmap of cylinder groups for which the + * free-block bitmap has changed since the snapshot operation began. + */ +#define NOCSPTRS ((128 / sizeof(void *)) - 4) + +/* + * A summary of contiguous blocks of various sizes is maintained + * in each cylinder group. Normally this is set by the initial + * value of fs_maxcontig. To conserve space, a maximum summary size + * is set by FS_MAXCONTIG. + */ +#define FS_MAXCONTIG 16 + +/* + * MINFREE gives the minimum acceptable percentage of filesystem + * blocks which may be free. If the freelist drops below this level + * only the superuser may continue to allocate blocks. This may + * be set to 0 if no reserve of free blocks is deemed necessary, + * however throughput drops by fifty percent if the filesystem + * is run at between 95% and 100% full; thus the minimum default + * value of fs_minfree is 5%. However, to get good clustering + * performance, 10% is a better choice. hence we use 10% as our + * default value. With 10% free space, fragmentation is not a + * problem, so we choose to optimize for time. + */ +#define MINFREE 8 +#define DEFAULTOPT FS_OPTTIME + +/* + * Grigoriy Orlov has done some extensive work to fine + * tune the layout preferences for directories within a filesystem. + * His algorithm can be tuned by adjusting the following parameters + * which tell the system the average file size and the average number + * of files per directory. These defaults are well selected for typical + * filesystems, but may need to be tuned for odd cases like filesystems + * being used for sqiud caches or news spools. + */ +#define AVFILESIZ 16384 /* expected average file size */ +#define AFPDIR 64 /* expected number of files per directory */ + +/* + * The maximum number of snapshot nodes that can be associated + * with each filesystem. This limit affects only the number of + * snapshot files that can be recorded within the superblock so + * that they can be found when the filesystem is mounted. However, + * maintaining too many will slow the filesystem performance, so + * having this limit is a good idea. + */ +#define FSMAXSNAP 20 + +/* + * Used to identify special blocks in snapshots: + * + * BLK_NOCOPY - A block that was unallocated at the time the snapshot + * was taken, hence does not need to be copied when written. + * BLK_SNAP - A block held by another snapshot that is not needed by this + * snapshot. When the other snapshot is freed, the BLK_SNAP entries + * are converted to BLK_NOCOPY. These are needed to allow fsck to + * identify blocks that are in use by other snapshots (which are + * expunged from this snapshot). + */ +#define BLK_NOCOPY ((ufs2_daddr_t)(1)) +#define BLK_SNAP ((ufs2_daddr_t)(2)) + +/* + * Sysctl values for the fast filesystem. + */ +#define FFS_ADJ_REFCNT 1 /* adjust inode reference count */ +#define FFS_ADJ_BLKCNT 2 /* adjust inode used block count */ +#define FFS_BLK_FREE 3 /* free range of blocks in map */ +#define FFS_DIR_FREE 4 /* free specified dir inodes in map */ +#define FFS_FILE_FREE 5 /* free specified file inodes in map */ +#define FFS_SET_FLAGS 6 /* set filesystem flags */ +#define FFS_MAXID 7 /* number of valid ffs ids */ + +/* + * Command structure passed in to the filesystem to adjust filesystem values. + */ +#define FFS_CMD_VERSION 0x19790518 /* version ID */ +struct fsck_cmd { + int32_t version; /* version of command structure */ + int32_t handle; /* reference to filesystem to be changed */ + int64_t value; /* inode or block number to be affected */ + int64_t size; /* amount or range to be adjusted */ + int64_t spare; /* reserved for future use */ +}; + +/* + * Per cylinder group information; summarized in blocks allocated + * from first cylinder group data blocks. These blocks have to be + * read in from fs_csaddr (size fs_cssize) in addition to the + * super block. + */ +struct csum { + int32_t cs_ndir; /* number of directories */ + int32_t cs_nbfree; /* number of free blocks */ + int32_t cs_nifree; /* number of free inodes */ + int32_t cs_nffree; /* number of free frags */ +}; +struct csum_total { + int64_t cs_ndir; /* number of directories */ + int64_t cs_nbfree; /* number of free blocks */ + int64_t cs_nifree; /* number of free inodes */ + int64_t cs_nffree; /* number of free frags */ + int64_t cs_numclusters; /* number of free clusters */ + int64_t cs_spare[3]; /* future expansion */ +}; + +/* + * Super block for an FFS filesystem. + */ +struct fs { + int32_t fs_firstfield; /* historic filesystem linked list, */ + int32_t fs_unused_1; /* used for incore super blocks */ + int32_t fs_sblkno; /* offset of super-block in filesys */ + int32_t fs_cblkno; /* offset of cyl-block in filesys */ + int32_t fs_iblkno; /* offset of inode-blocks in filesys */ + int32_t fs_dblkno; /* offset of first data after cg */ + int32_t fs_old_cgoffset; /* cylinder group offset in cylinder */ + int32_t fs_old_cgmask; /* used to calc mod fs_ntrak */ + int32_t fs_old_time; /* last time written */ + int32_t fs_old_size; /* number of blocks in fs */ + int32_t fs_old_dsize; /* number of data blocks in fs */ + int32_t fs_ncg; /* number of cylinder groups */ + int32_t fs_bsize; /* size of basic blocks in fs */ + int32_t fs_fsize; /* size of frag blocks in fs */ + int32_t fs_frag; /* number of frags in a block in fs */ +/* these are configuration parameters */ + int32_t fs_minfree; /* minimum percentage of free blocks */ + int32_t fs_old_rotdelay; /* num of ms for optimal next block */ + int32_t fs_old_rps; /* disk revolutions per second */ +/* these fields can be computed from the others */ + int32_t fs_bmask; /* ``blkoff'' calc of blk offsets */ + int32_t fs_fmask; /* ``fragoff'' calc of frag offsets */ + int32_t fs_bshift; /* ``lblkno'' calc of logical blkno */ + int32_t fs_fshift; /* ``numfrags'' calc number of frags */ +/* these are configuration parameters */ + int32_t fs_maxcontig; /* max number of contiguous blks */ + int32_t fs_maxbpg; /* max number of blks per cyl group */ +/* these fields can be computed from the others */ + int32_t fs_fragshift; /* block to frag shift */ + int32_t fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ + int32_t fs_sbsize; /* actual size of super block */ + int32_t fs_spare1[2]; /* old fs_csmask */ + /* old fs_csshift */ + int32_t fs_nindir; /* value of NINDIR */ + int32_t fs_inopb; /* value of INOPB */ + int32_t fs_old_nspf; /* value of NSPF */ +/* yet another configuration parameter */ + int32_t fs_optim; /* optimization preference, see below */ + int32_t fs_old_npsect; /* # sectors/track including spares */ + int32_t fs_old_interleave; /* hardware sector interleave */ + int32_t fs_old_trackskew; /* sector 0 skew, per track */ + int32_t fs_id[2]; /* unique filesystem id */ +/* sizes determined by number of cylinder groups and their sizes */ + int32_t fs_old_csaddr; /* blk addr of cyl grp summary area */ + int32_t fs_cssize; /* size of cyl grp summary area */ + int32_t fs_cgsize; /* cylinder group size */ + int32_t fs_spare2; /* old fs_ntrak */ + int32_t fs_old_nsect; /* sectors per track */ + int32_t fs_old_spc; /* sectors per cylinder */ + int32_t fs_old_ncyl; /* cylinders in filesystem */ + int32_t fs_old_cpg; /* cylinders per group */ + int32_t fs_ipg; /* inodes per group */ + int32_t fs_fpg; /* blocks per group * fs_frag */ +/* this data must be re-computed after crashes */ + struct csum fs_old_cstotal; /* cylinder summary information */ +/* these fields are cleared at mount time */ + int8_t fs_fmod; /* super block modified flag */ + int8_t fs_clean; /* filesystem is clean flag */ + int8_t fs_ronly; /* mounted read-only flag */ + int8_t fs_old_flags; /* old FS_ flags */ + u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */ + u_char fs_volname[MAXVOLLEN]; /* volume name */ + u_int64_t fs_swuid; /* system-wide uid */ + int32_t fs_pad; /* due to alignment of fs_swuid */ +/* these fields retain the current block allocation info */ + int32_t fs_cgrotor; /* last cg searched */ + void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */ + u_int8_t *fs_contigdirs; /* # of contiguously allocated dirs */ + struct csum *fs_csp; /* cg summary info buffer for fs_cs */ + int32_t *fs_maxcluster; /* max cluster in each cyl group */ + u_int *fs_active; /* used by snapshots to track fs */ + int32_t fs_old_cpc; /* cyl per cycle in postbl */ + int32_t fs_maxbsize; /* maximum blocking factor permitted */ + int64_t fs_sparecon64[17]; /* old rotation block list head */ + int64_t fs_sblockloc; /* byte offset of standard superblock */ + struct csum_total fs_cstotal; /* cylinder summary information */ + ufs_time_t fs_time; /* last time written */ + int64_t fs_size; /* number of blocks in fs */ + int64_t fs_dsize; /* number of data blocks in fs */ + ufs2_daddr_t fs_csaddr; /* blk addr of cyl grp summary area */ + int64_t fs_pendingblocks; /* blocks in process of being freed */ + int32_t fs_pendinginodes; /* inodes in process of being freed */ + int32_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */ + int32_t fs_avgfilesize; /* expected average file size */ + int32_t fs_avgfpdir; /* expected # of files per directory */ + int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */ + int32_t fs_sparecon32[26]; /* reserved for future constants */ + int32_t fs_flags; /* see FS_ flags below */ + int32_t fs_contigsumsize; /* size of cluster summary array */ + int32_t fs_maxsymlinklen; /* max length of an internal symlink */ + int32_t fs_old_inodefmt; /* format of on-disk inodes */ + u_int64_t fs_maxfilesize; /* maximum representable file size */ + int64_t fs_qbmask; /* ~fs_bmask for use with 64-bit size */ + int64_t fs_qfmask; /* ~fs_fmask for use with 64-bit size */ + int32_t fs_state; /* validate fs_clean field */ + int32_t fs_old_postblformat; /* format of positional layout tables */ + int32_t fs_old_nrpos; /* number of rotational positions */ + int32_t fs_spare5[2]; /* old fs_postbloff */ + /* old fs_rotbloff */ + int32_t fs_magic; /* magic number */ +}; + +/* Sanity checking. */ +#ifdef CTASSERT +CTASSERT(sizeof(struct fs) == 1376); +#endif + +/* + * Filesystem identification + */ +#define FS_UFS1_MAGIC 0x011954 /* UFS1 fast filesystem magic number */ +#define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast filesystem magic number */ +#define FS_OKAY 0x7c269d38 /* superblock checksum */ +#define FS_42INODEFMT -1 /* 4.2BSD inode format */ +#define FS_44INODEFMT 2 /* 4.4BSD inode format */ + +/* + * Preference for optimization. + */ +#define FS_OPTTIME 0 /* minimize allocation time */ +#define FS_OPTSPACE 1 /* minimize disk fragmentation */ + +/* + * Filesystem flags. + * + * The FS_UNCLEAN flag is set by the kernel when the filesystem was + * mounted with fs_clean set to zero. The FS_DOSOFTDEP flag indicates + * that the filesystem should be managed by the soft updates code. + * Note that the FS_NEEDSFSCK flag is set and cleared only by the + * fsck utility. It is set when background fsck finds an unexpected + * inconsistency which requires a traditional foreground fsck to be + * run. Such inconsistencies should only be found after an uncorrectable + * disk error. A foreground fsck will clear the FS_NEEDSFSCK flag when + * it has successfully cleaned up the filesystem. The kernel uses this + * flag to enforce that inconsistent filesystems be mounted read-only. + * The FS_INDEXDIRS flag when set indicates that the kernel maintains + * on-disk auxiliary indexes (such as B-trees) for speeding directory + * accesses. Kernels that do not support auxiliary indicies clear the + * flag to indicate that the indicies need to be rebuilt (by fsck) before + * they can be used. + * + * FS_ACLS indicates that ACLs are administratively enabled for the + * file system, so they should be loaded from extended attributes, + * observed for access control purposes, and be administered by object + * owners. FS_MULTILABEL indicates that the TrustedBSD MAC Framework + * should attempt to back MAC labels into extended attributes on the + * file system rather than maintain a single mount label for all + * objects. + */ +#define FS_UNCLEAN 0x01 /* filesystem not clean at mount */ +#define FS_DOSOFTDEP 0x02 /* filesystem using soft dependencies */ +#define FS_NEEDSFSCK 0x04 /* filesystem needs sync fsck before mount */ +#define FS_INDEXDIRS 0x08 /* kernel supports indexed directories */ +#define FS_ACLS 0x10 /* file system has ACLs enabled */ +#define FS_MULTILABEL 0x20 /* file system is MAC multi-label */ +#define FS_FLAGS_UPDATED 0x80 /* flags have been moved to new location */ + +/* + * Macros to access bits in the fs_active array. + */ +#define ACTIVECGNUM(fs, cg) ((fs)->fs_active[(cg) / (NBBY * sizeof(int))]) +#define ACTIVECGOFF(cg) (1 << ((cg) % (NBBY * sizeof(int)))) + +/* + * The size of a cylinder group is calculated by CGSIZE. The maximum size + * is limited by the fact that cylinder groups are at most one block. + * Its size is derived from the size of the maps maintained in the + * cylinder group and the (struct cg) size. + */ +#define CGSIZE(fs) \ + /* base cg */ (sizeof(struct cg) + sizeof(int32_t) + \ + /* old btotoff */ (fs)->fs_old_cpg * sizeof(int32_t) + \ + /* old boff */ (fs)->fs_old_cpg * sizeof(u_int16_t) + \ + /* inode map */ howmany((fs)->fs_ipg, NBBY) + \ + /* block map */ howmany((fs)->fs_fpg, NBBY) +\ + /* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \ + /* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) + \ + /* cluster map */ howmany(fragstoblks(fs, (fs)->fs_fpg), NBBY))) + +/* + * The minimal number of cylinder groups that should be created. + */ +#define MINCYLGRPS 4 + +/* + * Convert cylinder group to base address of its global summary info. + */ +#define fs_cs(fs, indx) fs_csp[indx] + +/* + * Cylinder group block for a filesystem. + */ +#define CG_MAGIC 0x090255 +struct cg { + int32_t cg_firstfield; /* historic cyl groups linked list */ + int32_t cg_magic; /* magic number */ + int32_t cg_old_time; /* time last written */ + int32_t cg_cgx; /* we are the cgx'th cylinder group */ + int16_t cg_old_ncyl; /* number of cyl's this cg */ + int16_t cg_old_niblk; /* number of inode blocks this cg */ + int32_t cg_ndblk; /* number of data blocks this cg */ + struct csum cg_cs; /* cylinder summary information */ + int32_t cg_rotor; /* position of last used block */ + int32_t cg_frotor; /* position of last used frag */ + int32_t cg_irotor; /* position of last used inode */ + int32_t cg_frsum[MAXFRAG]; /* counts of available frags */ + int32_t cg_old_btotoff; /* (int32) block totals per cylinder */ + int32_t cg_old_boff; /* (u_int16) free block positions */ + int32_t cg_iusedoff; /* (u_int8) used inode map */ + int32_t cg_freeoff; /* (u_int8) free block map */ + int32_t cg_nextfreeoff; /* (u_int8) next available space */ + int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */ + int32_t cg_clusteroff; /* (u_int8) free cluster map */ + int32_t cg_nclusterblks; /* number of clusters this cg */ + int32_t cg_niblk; /* number of inode blocks this cg */ + int32_t cg_initediblk; /* last initialized inode */ + int32_t cg_sparecon32[3]; /* reserved for future use */ + ufs_time_t cg_time; /* time last written */ + int64_t cg_sparecon64[3]; /* reserved for future use */ + u_int8_t cg_space[1]; /* space for cylinder group maps */ +/* actually longer */ +}; + +/* + * Macros for access to cylinder group array structures + */ +#define cg_chkmagic(cgp) ((cgp)->cg_magic == CG_MAGIC) +#define cg_inosused(cgp) \ + ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff)) +#define cg_blksfree(cgp) \ + ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_freeoff)) +#define cg_clustersfree(cgp) \ + ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_clusteroff)) +#define cg_clustersum(cgp) \ + ((int32_t *)((u_int8_t *)(cgp) + (cgp)->cg_clustersumoff)) + +/* + * Turn filesystem block numbers into disk block addresses. + * This maps filesystem blocks to device size blocks. + */ +#define fsbtodb(fs, b) ((b) << (fs)->fs_fsbtodb) +#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb) + +/* + * Cylinder group macros to locate things in cylinder groups. + * They calc filesystem addresses of cylinder group data structures. + */ +#define cgbase(fs, c) (((ufs2_daddr_t)(fs)->fs_fpg) * (c)) +#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */ +#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */ +#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */ +#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */ +#define cgstart(fs, c) \ + ((fs)->fs_magic == FS_UFS2_MAGIC ? cgbase(fs, c) : \ + (cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask)))) + +/* + * Macros for handling inode numbers: + * inode number to filesystem block offset. + * inode number to cylinder group number. + * inode number to filesystem block address. + */ +#define ino_to_cg(fs, x) ((x) / (fs)->fs_ipg) +#define ino_to_fsba(fs, x) \ + ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + \ + (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs)))))) +#define ino_to_fsbo(fs, x) ((x) % INOPB(fs)) + +/* + * Give cylinder group number for a filesystem block. + * Give cylinder group block number for a filesystem block. + */ +#define dtog(fs, d) ((d) / (fs)->fs_fpg) +#define dtogd(fs, d) ((d) % (fs)->fs_fpg) + +/* + * Extract the bits for a block from a map. + * Compute the cylinder and rotational position of a cyl block addr. + */ +#define blkmap(fs, map, loc) \ + (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag))) + +/* + * The following macros optimize certain frequently calculated + * quantities by using shifts and masks in place of divisions + * modulos and multiplications. + */ +#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \ + ((loc) & (fs)->fs_qbmask) +#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \ + ((loc) & (fs)->fs_qfmask) +#define lfragtosize(fs, frag) /* calculates ((off_t)frag * fs->fs_fsize) */ \ + (((off_t)(frag)) << (fs)->fs_fshift) +#define lblktosize(fs, blk) /* calculates ((off_t)blk * fs->fs_bsize) */ \ + (((off_t)(blk)) << (fs)->fs_bshift) +/* Use this only when `blk' is known to be small, e.g., < NDADDR. */ +#define smalllblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \ + ((blk) << (fs)->fs_bshift) +#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \ + ((loc) >> (fs)->fs_bshift) +#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ + ((loc) >> (fs)->fs_fshift) +#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \ + (((size) + (fs)->fs_qbmask) & (fs)->fs_bmask) +#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \ + (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask) +#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \ + ((frags) >> (fs)->fs_fragshift) +#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \ + ((blks) << (fs)->fs_fragshift) +#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \ + ((fsb) & ((fs)->fs_frag - 1)) +#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \ + ((fsb) &~ ((fs)->fs_frag - 1)) + +/* + * Determine the number of available frags given a + * percentage to hold in reserve. + */ +#define freespace(fs, percentreserved) \ + (blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \ + (fs)->fs_cstotal.cs_nffree - \ + (((off_t)((fs)->fs_dsize)) * (percentreserved) / 100)) + +/* + * Determining the size of a file block in the filesystem. + */ +#define blksize(fs, ip, lbn) \ + (((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \ + ? (fs)->fs_bsize \ + : (fragroundup(fs, blkoff(fs, (ip)->i_size)))) +#define sblksize(fs, size, lbn) \ + (((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \ + ? (fs)->fs_bsize \ + : (fragroundup(fs, blkoff(fs, (size))))) + + +/* + * Number of inodes in a secondary storage block/fragment. + */ +#define INOPB(fs) ((fs)->fs_inopb) +#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift) + +/* + * Number of indirects in a filesystem block. + */ +#define NINDIR(fs) ((fs)->fs_nindir) + +extern int inside[], around[]; +extern u_char *fragtbl[]; + +#endif diff --git a/sys/boot/common/help.common b/sys/boot/common/help.common index bc09c67adb..9032a09f40 100644 --- a/sys/boot/common/help.common +++ b/sys/boot/common/help.common @@ -5,6 +5,7 @@ ? The help command displays help on commands and their usage. + $DragonFly: src/sys/boot/common/help.common,v 1.2 2003/11/10 06:08:31 dillon Exp $ In command help, a term enclosed with <...> indicates a value as described by the term. A term enclosed with [...] is optional, @@ -13,6 +14,11 @@ Some commands may not be available. Use the '?' command to list most available commands. + If needed, disable the use of ACPI with: + + unset acpi_load + $hint.acpi.0.disabled="1" + ################################################################################ # Tautoboot DBoot after a delay @@ -128,7 +134,7 @@ Sets the default set of kernel boot filename(s). It may be overridden by setting the bootfile variable to a semicolon-separated list of filenames, each of which will be searched for in the module_path - directories. The default bootfile set is "kernel;kernel.old". + directories. The default bootfile set is "kernel". ################################################################################ # Tset Sboot_askname DPrompt for root device @@ -200,7 +206,7 @@ Sets the list of directories which will be searched in for modules named in a load command or implicitly required by a dependency. The - default module_path is "/;/boot;/modules". + default module_path is "/boot/kernel;/boot/modules". ################################################################################ # Tset Sprompt DSet the command prompt @@ -234,25 +240,31 @@ cannot be set below the default determined when the kernel was compiled. + set kern.ipc.nsfbufs= NSFBUFS + + Set the number of sendfile buffers to be allocated. This + overrides the value determined when the kernel was compiled. + set kern.vm.kmem.size= VM_KMEM_SIZE Sets the size of kernel memory (bytes). This overrides - completely the value determined when the kernel was - compiled. + the value determined when the kernel was compiled. - set machdep.pccard.pcic_irq= + set machdep.disable_mtrrs=1 - Overrides the IRQ normally assigned to a PCCARD controller. - Typically the first available interrupt will be allocated, - which may conflict with other hardware. If this value is - set to 0, an interrupt will not be assigned and the - controller will operate in polled mode only. + Disable the use of i686 MTRRs (i386 only) set net.inet.tcp.tcbhashsize= TCBHASHSIZE Overrides the compile-time set value of TCBHASHSIZE or the preset default of 512. Must be a power of 2. + hw.syscons.sc_no_suspend_vtswitch= + + Disable VT switching on suspend. + + value is 0 (default) or non-zero to enable. + set hw.physmem= MAXMEM (i386 only) Limits the amount of physical memory space available to @@ -265,6 +277,21 @@ this option provides a hint as to the actual size of system memory (which will be tested before use). + set hw.pci.allow_unsupported_io_range= + + Allow the PCI Bridge to pass through an unsupported + memory range assigned by the BIOS. + + value is 0 (default) or non-zero to enable. + + set hw.pci.enable_io_modes= + + Enable PCI resources which are left off by some BIOSes + or are not enabled correctly by the device driver. + + value is 1 (default), but this may cause problems with + some peripherals. Set to 0 to disable. + ################################################################################ # Tshow DShow the values of variables diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c index 6ac6f47db0..7d72ae0d63 100644 --- a/sys/boot/common/interp.c +++ b/sys/boot/common/interp.c @@ -23,9 +23,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/interp.c,v 1.22.2.5 2001/03/04 04:46:18 obrien Exp $ - * $DragonFly: src/sys/boot/common/interp.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/interp.c,v 1.29 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/interp.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ + /* * Simple commandline interpreter, toplevel and misc. * @@ -119,7 +120,7 @@ interact(void) if (getenv("prompt") == NULL) setenv("prompt", "${interpret}", 1); if (getenv("interpret") == NULL) - setenv("interpret", "ok", 1); + setenv("interpret", "OK", 1); for (;;) { diff --git a/sys/boot/common/interp_backslash.c b/sys/boot/common/interp_backslash.c index 1d4093ae13..fa5925b9e0 100644 --- a/sys/boot/common/interp_backslash.c +++ b/sys/boot/common/interp_backslash.c @@ -1,4 +1,4 @@ -/* +/*- * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -11,10 +11,10 @@ * Jordan K. Hubbard * 29 August 1998 * - * $FreeBSD: src/sys/boot/common/interp_backslash.c,v 1.4.2.1 2000/12/28 13:12:34 ps Exp $ - * $DragonFly: src/sys/boot/common/interp_backslash.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ - * * Routine for doing backslash elimination. + * + * $FreeBSD: src/sys/boot/common/interp_backslash.c,v 1.6 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/interp_backslash.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/common/interp_forth.c b/sys/boot/common/interp_forth.c index b6212b561b..8dd78a12d3 100644 --- a/sys/boot/common/interp_forth.c +++ b/sys/boot/common/interp_forth.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1998 Michael Smith * All rights reserved. * @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/interp_forth.c,v 1.15.2.2 2000/12/28 13:12:34 ps Exp $ - * $DragonFly: src/sys/boot/common/interp_forth.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/interp_forth.c,v 1.23 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/interp_forth.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include /* to pick up __FreeBSD_version */ @@ -38,7 +38,7 @@ extern char bootprog_rev[]; /* #define BFORTH_DEBUG */ #ifdef BFORTH_DEBUG -# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args) +# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args) #else # define DEBUG(fmt, args...) #endif @@ -54,6 +54,7 @@ extern char bootprog_rev[]; * BootForth Interface to Ficl Forth interpreter. */ +FICL_SYSTEM *bf_sys; FICL_VM *bf_vm; FICL_WORD *pInterp; @@ -233,8 +234,8 @@ bf_init(void) char create_buf[41]; /* 31 characters-long builtins */ int fd; - ficlInitSystem(10000); /* Default dictionary ~4000 cells */ - bf_vm = ficlNewVM(); + bf_sys = ficlInitSystem(10000); /* Default dictionary ~4000 cells */ + bf_vm = ficlNewVM(bf_sys); /* Put all private definitions in a "builtins" vocabulary */ ficlExec(bf_vm, "vocabulary builtins also builtins definitions"); @@ -244,7 +245,7 @@ bf_init(void) /* make all commands appear as Forth words */ SET_FOREACH(cmdp, Xcommand_set) { - ficlBuild((*cmdp)->c_name, bf_command, FW_DEFAULT); + ficlBuild(bf_sys, (char *)(*cmdp)->c_name, bf_command, FW_DEFAULT); ficlExec(bf_vm, "forth definitions builtins"); sprintf(create_buf, "builtin: %s", (*cmdp)->c_name); ficlExec(bf_vm, create_buf); @@ -253,8 +254,8 @@ bf_init(void) ficlExec(bf_vm, "only forth definitions"); /* Export some version numbers so that code can detect the loader/host version */ - ficlSetEnv("FreeBSD_version", __FreeBSD_version); - ficlSetEnv("loader_version", + ficlSetEnv(bf_sys, "FreeBSD_version", __FreeBSD_version); + ficlSetEnv(bf_sys, "loader_version", (bootprog_rev[0] - '0') * 10 + (bootprog_rev[2] - '0')); /* try to load and run init file if present */ @@ -264,7 +265,7 @@ bf_init(void) } /* Do this last, so /boot/boot.4th can change it */ - pInterp = ficlLookup("interpret"); + pInterp = ficlLookup(bf_sys, "interpret"); } /* @@ -300,7 +301,7 @@ bf_run(char *line) if (result == VM_USEREXIT) panic("interpreter exit"); - setenv("interpret", bf_vm->state ? "" : "ok", 1); + setenv("interpret", bf_vm->state ? "" : "OK", 1); return result; } diff --git a/sys/boot/common/interp_parse.c b/sys/boot/common/interp_parse.c index f357b57962..5fa2ddc408 100644 --- a/sys/boot/common/interp_parse.c +++ b/sys/boot/common/interp_parse.c @@ -1,4 +1,4 @@ -/* +/*- * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -11,10 +11,10 @@ * Jordan K. Hubbard * 29 August 1998 * - * $FreeBSD: src/sys/boot/common/interp_parse.c,v 1.8.2.1 2000/12/28 13:12:35 ps Exp $ - * $DragonFly: src/sys/boot/common/interp_parse.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ - * * The meat of the simple parser. + * + * $FreeBSD: src/sys/boot/common/interp_parse.c,v 1.10 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/interp_parse.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/common/isapnp.c b/sys/boot/common/isapnp.c index 0a1e4934ca..c20867c02a 100644 --- a/sys/boot/common/isapnp.c +++ b/sys/boot/common/isapnp.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1998, Michael Smith * Copyright (c) 1996, Sujal M. Patel * All rights reserved. @@ -24,8 +24,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/isapnp.c,v 1.5.2.1 2000/12/28 13:12:35 ps Exp $ - * $DragonFly: src/sys/boot/common/isapnp.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/isapnp.c,v 1.7 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/isapnp.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* diff --git a/sys/boot/common/isapnp.h b/sys/boot/common/isapnp.h index 9a82d5771f..f30c91472d 100644 --- a/sys/boot/common/isapnp.h +++ b/sys/boot/common/isapnp.h @@ -29,8 +29,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/isapnp.h,v 1.5 1999/12/29 04:54:22 peter Exp $ - * $DragonFly: src/sys/boot/common/isapnp.h,v 1.3 2003/08/27 11:42:33 rob Exp $ + * $FreeBSD: src/sys/boot/common/isapnp.h,v 1.7 2002/03/20 07:59:37 alfred Exp $ + * $DragonFly: src/sys/boot/common/isapnp.h,v 1.4 2003/11/10 06:08:31 dillon Exp $ */ #ifndef _I386_ISA_PNP_H_ @@ -297,8 +297,6 @@ extern pnp_id pnp_devices[MAX_PNP_CARDS]; extern struct pnp_cinfo pnp_ldn_overrides[MAX_PNP_LDN]; extern int pnp_overrides_valid; -extern struct linker_set pnpdevice_set; - /* * these two functions are for use in drivers */ @@ -309,7 +307,7 @@ int enable_pnp_card(void); /* * used by autoconfigure to actually probe and attach drivers */ -void pnp_configure (void); +void pnp_configure(void); #endif /* _KERNEL */ diff --git a/sys/boot/common/load.c b/sys/boot/common/load.c index 50f36cb61b..9646ef5742 100644 --- a/sys/boot/common/load.c +++ b/sys/boot/common/load.c @@ -23,10 +23,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/load.c,v 1.2 1999/08/28 00:39:49 peter Exp $ - * $DragonFly: src/sys/boot/common/load.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/load.c,v 1.3 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/load.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ - #include #define LOAD_TINYBUF 2048 diff --git a/sys/boot/common/load_aout.c b/sys/boot/common/load_aout.c deleted file mode 100644 index 48447b31b6..0000000000 --- a/sys/boot/common/load_aout.c +++ /dev/null @@ -1,262 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith - * All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD: src/sys/boot/common/load_aout.c,v 1.16.2.2 2000/12/28 13:12:35 ps Exp $ - * $DragonFly: src/sys/boot/common/Attic/load_aout.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define FREEBSD_AOUT -#include - -#include "bootstrap.h" - -static int aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel); - -#if 0 -static vm_offset_t aout_findkldident(struct loaded_module *mp, struct exec *ehdr); -static int aout_fixupkldmod(struct loaded_module *mp, struct exec *ehdr); -#endif - -const char *aout_kerneltype = "a.out kernel"; -const char *aout_moduletype = "a.out module"; - -/* - * Attempt to load the file (file) as an a.out module. It will be stored at - * (dest), and a pointer to a module structure describing the loaded object - * will be saved in (result). - */ -int -aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) -{ - struct loaded_module *mp, *kmp; - struct exec ehdr; - int fd; - vm_offset_t addr; - int err, kernel; - u_int pad; - char *s; - - mp = NULL; - - /* - * Open the image, read and validate the a.out header - */ - if (filename == NULL) /* can't handle nameless */ - return(EFTYPE); - if ((fd = open(filename, O_RDONLY)) == -1) - return(errno); - if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) { - err = EFTYPE; /* could be EIO, but may be small file */ - goto oerr; - } - if (N_BADMAG(ehdr)) { - err = EFTYPE; - goto oerr; - } - - /* - * Check to see what sort of module we are. - * - * XXX should check N_GETMID() - */ - kmp = mod_findmodule(NULL, NULL); - if ((N_GETFLAG(ehdr)) & EX_DYNAMIC) { - /* Looks like a kld module */ - if (kmp == NULL) { - printf("aout_loadmodule: can't load module before kernel\n"); - err = EPERM; - goto oerr; - } - if (strcmp(aout_kerneltype, kmp->m_type)) { - printf("aout_loadmodule: can't load module with kernel type '%s'\n", kmp->m_type); - err = EPERM; - goto oerr; - } - /* Looks OK, got ahead */ - kernel = 0; - - } else if (N_GETFLAG(ehdr) == 0) { - /* Looks like a kernel */ - if (kmp != NULL) { - printf("aout_loadmodule: kernel already loaded\n"); - err = EPERM; - goto oerr; - } - /* - * Calculate destination address based on kernel entrypoint - * XXX this is i386-freebsd-aout specific - */ - dest = ehdr.a_entry & 0x100000; - if (dest == 0) { - printf("aout_loadmodule: not a kernel (maybe static binary?)\n"); - err = EPERM; - goto oerr; - } - kernel = 1; - } else { - err = EFTYPE; - goto oerr; - } - - /* - * Ok, we think we should handle this. - */ - mp = mod_allocmodule(); - if (kernel) - setenv("kernelname", filename, 1); - s = strrchr(filename, '/'); - if (s) - mp->m_name = strdup(s + 1); - else - mp->m_name = strdup(filename); - mp->m_type = strdup(kernel ? aout_kerneltype : aout_moduletype); - - /* Page-align the load address */ - addr = dest; - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } - mp->m_addr = addr; /* save the aligned load address */ - if (kernel) - printf("%s at %p\n", filename, (void *) addr); - - mp->m_size = aout_loadimage(mp, fd, addr, &ehdr, kernel); - if (mp->m_size == 0) - goto ioerr; - -#if 0 - /* Handle KLD module data */ - if (!kernel && ((err = aout_fixupkldmod(mp, &ehdr)) != 0)) - goto oerr; -#endif - - /* save exec header as metadata */ - mod_addmetadata(mp, MODINFOMD_AOUTEXEC, sizeof(struct exec), &ehdr); - - /* Load OK, return module pointer */ - *result = (struct loaded_module *)mp; - err = 0; - goto out; - - ioerr: - err = EIO; - oerr: - mod_discard(mp); - out: - close(fd); - return(err); -} - -/* - * With the file (fd) open on the image, and (ehdr) containing - * the exec header, load the image at (addr) - * - * Fixup the a_bss field in (ehdr) to reflect the padding added to - * align the symbol table. - */ -static int -aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel) -{ - u_int pad; - vm_offset_t addr; - size_t ss; - ssize_t result; - vm_offset_t ssym, esym; - - addr = loadaddr; - lseek(fd, (off_t)N_TXTOFF(*ehdr), SEEK_SET); - - /* text segment */ - printf(" text=0x%lx ", ehdr->a_text); - result = archsw.arch_readin(fd, addr, ehdr->a_text); - if (result < 0 || (size_t)result != ehdr->a_text) - return(0); - addr += ehdr->a_text; - - /* data segment */ - printf("data=0x%lx ", ehdr->a_data); - result = archsw.arch_readin(fd, addr, ehdr->a_data); - if (result < 0 || (size_t)result != ehdr->a_data) - return(0); - addr += ehdr->a_data; - - /* For kernels, we pad the BSS to a page boundary */ - if (kernel) { - pad = (u_int)ehdr->a_bss & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - ehdr->a_bss += pad; - } - } - printf("bss=0x%lx ", ehdr->a_bss); - addr += ehdr->a_bss; - - /* symbol table size */ - ssym = esym = addr; - if(ehdr->a_syms!=NULL) { - archsw.arch_copyin(&ehdr->a_syms, addr, sizeof(ehdr->a_syms)); - addr += sizeof(ehdr->a_syms); - - /* symbol table */ - printf("symbols=[0x%lx+0x%lx", (long)sizeof(ehdr->a_syms),ehdr->a_syms); - result = archsw.arch_readin(fd, addr, ehdr->a_syms); - if (result < 0 || (size_t)result != ehdr->a_syms) - return(0); - addr += ehdr->a_syms; - - /* string table */ - read(fd, &ss, sizeof(ss)); - archsw.arch_copyin(&ss, addr, sizeof(ss)); - addr += sizeof(ss); - ss -= sizeof(ss); - printf("+0x%lx+0x%x]", (long)sizeof(ss), ss); - result = archsw.arch_readin(fd, addr, ss); - if (result < 0 || (size_t)result != ss) - return(0); - addr += ss; - esym = addr; - - mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym); - mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym); - } else { - printf("symbols=[none]"); - } - printf("\n"); - - return(addr - loadaddr); -} - - diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c index 4c9cf420dc..8f00df2b88 100644 --- a/sys/boot/common/load_elf.c +++ b/sys/boot/common/load_elf.c @@ -24,16 +24,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/load_elf.c,v 1.13.2.1 2000/12/28 13:12:35 ps Exp $ - * $DragonFly: src/sys/boot/common/load_elf.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/load_elf.c,v 1.29 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/load_elf.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include #include -#include #include +#include #include -#include #include #include #define FREEBSD_ELF @@ -41,10 +40,46 @@ #include "bootstrap.h" -static int elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, Elf_Ehdr *ehdr, int kernel, caddr_t firstpage, int firstlen); +#define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l) -char *elf_kerneltype = "elf kernel"; -char *elf_moduletype = "elf module"; +#if defined(__i386__) && __ELF_WORD_SIZE == 64 +#undef ELF_TARG_CLASS +#undef ELF_TARG_MACH +#define ELF_TARG_CLASS ELFCLASS64 +#define ELF_TARG_MACH EM_X86_64 +#endif + +typedef struct elf_file { + Elf_Phdr *ph; + Elf_Ehdr *ehdr; + Elf_Sym *symtab; + Elf_Hashelt *hashtab; + Elf_Hashelt nbuckets; + Elf_Hashelt nchains; + Elf_Hashelt *buckets; + Elf_Hashelt *chains; + Elf_Rela *rela; + size_t relasz; + char *strtab; + size_t strsz; + int fd; + caddr_t firstpage; + size_t firstlen; + int kernel; + u_int64_t off; +} *elf_file_t; + +static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef, u_int64_t loadaddr); +static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef, const char* name, Elf_Sym* sym); +#ifdef __sparc__ +static void __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, + void *p, void *val, size_t len); +#endif +static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef); +static char *fake_modname(const char *name); + +const char *__elfN(kerneltype) = "elf kernel"; +const char *__elfN(moduletype) = "elf module"; /* * Attempt to load the file (file) as an ELF module. It will be stored at @@ -52,35 +87,37 @@ char *elf_moduletype = "elf module"; * will be saved in (result). */ int -elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) +__elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result) { - struct loaded_module *mp, *kmp; - Elf_Ehdr *ehdr; - int fd; - int err, kernel; + struct preloaded_file *fp, *kfp; + struct elf_file ef; + Elf_Ehdr *ehdr; + int err; u_int pad; - char *s; - caddr_t firstpage; - int firstlen; + ssize_t bytes_read; - mp = NULL; + fp = NULL; + bzero(&ef, sizeof(struct elf_file)); /* * Open the image, read and validate the ELF header */ if (filename == NULL) /* can't handle nameless */ return(EFTYPE); - if ((fd = open(filename, O_RDONLY)) == -1) + if ((ef.fd = open(filename, O_RDONLY)) == -1) return(errno); - firstpage = malloc(PAGE_SIZE); - if (firstpage == NULL) + ef.firstpage = malloc(PAGE_SIZE); + if (ef.firstpage == NULL) { + close(ef.fd); return(ENOMEM); - firstlen = read(fd, firstpage, PAGE_SIZE); - if (firstlen <= sizeof(ehdr)) { + } + bytes_read = read(ef.fd, ef.firstpage, PAGE_SIZE); + ef.firstlen = (size_t)bytes_read; + if (bytes_read < 0 || ef.firstlen <= sizeof(Elf_Ehdr)) { err = EFTYPE; /* could be EIO, but may be small file */ goto oerr; } - ehdr = (Elf_Ehdr *)firstpage; + ehdr = ef.ehdr = (Elf_Ehdr *)ef.firstpage; /* Is it ELF? */ if (!IS_ELF(*ehdr)) { @@ -100,21 +137,21 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) /* * Check to see what sort of module we are. */ - kmp = mod_findmodule(NULL, NULL); + kfp = file_findfile(NULL, NULL); if (ehdr->e_type == ET_DYN) { /* Looks like a kld module */ - if (kmp == NULL) { - printf("elf_loadmodule: can't load module before kernel\n"); + if (kfp == NULL) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module before kernel\n"); err = EPERM; goto oerr; } - if (strcmp(elf_kerneltype, kmp->m_type)) { - printf("elf_loadmodule: can't load module with kernel type '%s'\n", kmp->m_type); + if (strcmp(__elfN(kerneltype), kfp->f_type)) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); err = EPERM; goto oerr; } /* Looks OK, got ahead */ - kernel = 0; + ef.kernel = 0; /* Page-align the load address */ pad = (u_int)dest & PAGE_MASK; @@ -124,21 +161,21 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) } } else if (ehdr->e_type == ET_EXEC) { /* Looks like a kernel */ - if (kmp != NULL) { - printf("elf_loadmodule: kernel already loaded\n"); + if (kfp != NULL) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n"); err = EPERM; goto oerr; } /* * Calculate destination address based on kernel entrypoint */ - dest = (vm_offset_t) ehdr->e_entry; + dest = ehdr->e_entry; if (dest == 0) { - printf("elf_loadmodule: not a kernel (maybe static binary?)\n"); + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n"); err = EPERM; goto oerr; } - kernel = 1; + ef.kernel = 1; } else { err = EFTYPE; @@ -148,48 +185,44 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) /* * Ok, we think we should handle this. */ - mp = mod_allocmodule(); - if (mp == NULL) { - printf("elf_loadmodule: cannot allocate module info\n"); + fp = file_alloc(); + if (fp == NULL) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: cannot allocate module info\n"); err = EPERM; goto out; } - if (kernel) + if (ef.kernel) setenv("kernelname", filename, 1); - s = strrchr(filename, '/'); - if (s) - mp->m_name = strdup(s + 1); - else - mp->m_name = strdup(filename); - mp->m_type = strdup(kernel ? elf_kerneltype : elf_moduletype); + fp->f_name = strdup(filename); + fp->f_type = strdup(ef.kernel ? __elfN(kerneltype) : __elfN(moduletype)); #ifdef ELF_VERBOSE - if (kernel) - printf("%s entry at %p\n", filename, (void *) dest); + if (ef.kernel) + printf("%s entry at 0x%jx\n", filename, (uintmax_t)dest); #else printf("%s ", filename); #endif - mp->m_size = elf_loadimage(mp, fd, dest, ehdr, kernel, firstpage, firstlen); - if (mp->m_size == 0 || mp->m_addr == 0) + fp->f_size = __elfN(loadimage)(fp, &ef, dest); + if (fp->f_size == 0 || fp->f_addr == 0) goto ioerr; /* save exec header as metadata */ - mod_addmetadata(mp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr); + file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr); /* Load OK, return module pointer */ - *result = (struct loaded_module *)mp; + *result = (struct preloaded_file *)fp; err = 0; goto out; ioerr: err = EIO; oerr: - mod_discard(mp); + file_discard(fp); out: - if (firstpage) - free(firstpage); - close(fd); + if (ef.firstpage) + free(ef.firstpage); + close(ef.fd); return(err); } @@ -198,11 +231,12 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result) * the Elf header, load the image at (off) */ static int -elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, - Elf_Ehdr *ehdr, int kernel, caddr_t firstpage, int firstlen) +__elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) { - int i, j; - Elf_Phdr *phdr; + int i; + u_int j; + Elf_Ehdr *ehdr; + Elf_Phdr *phdr, *php; Elf_Shdr *shdr; int ret; vm_offset_t firstaddr; @@ -211,34 +245,38 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, size_t resid, chunk; ssize_t result; vm_offset_t dest; - vm_offset_t ssym, esym; + Elf_Addr ssym, esym; Elf_Dyn *dp; + Elf_Addr adp; int ndp; - char *s; - char *strtab; - size_t strsz; int symstrindex; int symtabindex; - long size; + Elf_Size size; u_int fpcopy; dp = NULL; shdr = NULL; ret = 0; firstaddr = lastaddr = 0; - if (kernel) { + ehdr = ef->ehdr; + if (ef->kernel) { #ifdef __i386__ +#if __ELF_WORD_SIZE == 64 + off = - (off & 0xffffffffff000000ull);/* x86_64 relocates after locore */ +#else off = - (off & 0xff000000u); /* i386 relocates after locore */ +#endif #else off = 0; /* alpha is direct mapped for kernels */ #endif } + ef->off = off; - if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > firstlen) { - printf("elf_loadimage: program header not within first page\n"); + if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: program header not within first page\n"); goto out; } - phdr = (Elf_Phdr *)(firstpage + ehdr->e_phoff); + phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++) { /* We want to load PT_LOAD segments only.. */ @@ -261,19 +299,20 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, } #endif fpcopy = 0; - if (firstlen > phdr[i].p_offset) { - fpcopy = firstlen - phdr[i].p_offset; - archsw.arch_copyin(firstpage + phdr[i].p_offset, + if (ef->firstlen > phdr[i].p_offset) { + fpcopy = ef->firstlen - phdr[i].p_offset; + archsw.arch_copyin(ef->firstpage + phdr[i].p_offset, phdr[i].p_vaddr + off, fpcopy); } if (phdr[i].p_filesz > fpcopy) { - if (lseek(fd, phdr[i].p_offset + fpcopy, SEEK_SET) == -1) { - printf("\nelf_loadexec: cannot seek\n"); + if (lseek(ef->fd, (off_t)(phdr[i].p_offset + fpcopy), + SEEK_SET) == -1) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadexec: cannot seek\n"); goto out; } - if (archsw.arch_readin(fd, phdr[i].p_vaddr + off + fpcopy, - phdr[i].p_filesz - fpcopy) != phdr[i].p_filesz - fpcopy) { - printf("\nelf_loadexec: archsw.readin failed\n"); + if (archsw.arch_readin(ef->fd, phdr[i].p_vaddr + off + fpcopy, + phdr[i].p_filesz - fpcopy) != (ssize_t)(phdr[i].p_filesz - fpcopy)) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadexec: archsw.readin failed\n"); goto out; } } @@ -287,6 +326,10 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, /* no archsw.arch_bzero */ buf = malloc(PAGE_SIZE); + if (buf == NULL) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: malloc() failed\n"); + goto out; + } bzero(buf, PAGE_SIZE); resid = phdr[i].p_memsz - phdr[i].p_filesz; dest = phdr[i].p_vaddr + off + phdr[i].p_filesz; @@ -321,12 +364,13 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, shdr = malloc(chunk); if (shdr == NULL) goto nosyms; - if (lseek(fd, ehdr->e_shoff, SEEK_SET) == -1) { - printf("\nelf_loadimage: cannot lseek() to section headers"); + if (lseek(ef->fd, (off_t)ehdr->e_shoff, SEEK_SET) == -1) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: cannot lseek() to section headers"); goto nosyms; } - if (read(fd, shdr, chunk) != chunk) { - printf("\nelf_loadimage: read section headers failed"); + result = read(ef->fd, shdr, chunk); + if (result < 0 || (size_t)result != chunk) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: read section headers failed"); goto nosyms; } symtabindex = -1; @@ -378,7 +422,7 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, size = shdr[i].sh_size; archsw.arch_copyin(&size, lastaddr, sizeof(size)); - lastaddr += sizeof(long); + lastaddr += sizeof(size); #ifdef ELF_VERBOSE printf("\n%s: 0x%lx@0x%lx -> 0x%lx-0x%lx", secname, @@ -387,25 +431,25 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, #else if (i == symstrindex) printf("+"); - printf("0x%lx+0x%lx", (long)sizeof(size), size); + printf("0x%lx+0x%lx", (long)sizeof(size), (long)size); #endif - if (lseek(fd, shdr[i].sh_offset, SEEK_SET) == -1) { - printf("\nelf_loadimage: could not seek for symbols - skipped!"); + if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not seek for symbols - skipped!"); lastaddr = ssym; ssym = 0; goto nosyms; } - if (archsw.arch_readin(fd, lastaddr, shdr[i].sh_size) != - shdr[i].sh_size) { - printf("\nelf_loadimage: could not read symbols - skipped!"); + result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size); + if (result < 0 || (size_t)result != shdr[i].sh_size) { + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not read symbols - skipped!"); lastaddr = ssym; ssym = 0; goto nosyms; } /* Reset offsets relative to ssym */ lastaddr += shdr[i].sh_size; - lastaddr = roundup(lastaddr, sizeof(long)); + lastaddr = roundup(lastaddr, sizeof(size)); if (i == symtabindex) symtabindex = -1; else if (i == symstrindex) @@ -416,68 +460,75 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off, printf("]"); #endif - mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym); - mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym); + file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym); + file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym); nosyms: printf("\n"); ret = lastaddr - firstaddr; - mp->m_addr = firstaddr; + fp->f_addr = firstaddr; + php = NULL; for (i = 0; i < ehdr->e_phnum; i++) { if (phdr[i].p_type == PT_DYNAMIC) { - dp = (Elf_Dyn *)(phdr[i].p_vaddr); - mod_addmetadata(mp, MODINFOMD_DYNAMIC, sizeof(dp), &dp); - dp = NULL; + php = phdr + i; + adp = php->p_vaddr; + file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp), &adp); break; } } - if (kernel) /* kernel must not depend on anything */ + if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */ goto out; - ndp = 0; - for (i = 0; i < ehdr->e_phnum; i++) { - if (phdr[i].p_type == PT_DYNAMIC) { - ndp = phdr[i].p_filesz / sizeof(Elf_Dyn); - dp = malloc(phdr[i].p_filesz); - archsw.arch_copyout(phdr[i].p_vaddr + off, dp, phdr[i].p_filesz); - } - } - if (dp == NULL || ndp == 0) + ndp = php->p_filesz / sizeof(Elf_Dyn); + if (ndp == 0) goto out; - strtab = NULL; - strsz = 0; + dp = malloc(php->p_filesz); + if (dp == NULL) + goto out; + archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz); + + ef->strsz = 0; for (i = 0; i < ndp; i++) { if (dp[i].d_tag == NULL) break; switch (dp[i].d_tag) { + case DT_HASH: + ef->hashtab = (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; case DT_STRTAB: - strtab = (char *)(dp[i].d_un.d_ptr + off); + ef->strtab = (char *)(uintptr_t)(dp[i].d_un.d_ptr + off); break; case DT_STRSZ: - strsz = dp[i].d_un.d_val; + ef->strsz = dp[i].d_un.d_val; + break; + case DT_SYMTAB: + ef->symtab = (Elf_Sym*)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; + case DT_RELA: + ef->rela = (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off); + break; + case DT_RELASZ: + ef->relasz = dp[i].d_un.d_val; break; default: break; } } - if (strtab == NULL || strsz == 0) + if (ef->hashtab == NULL || ef->symtab == NULL || + ef->strtab == NULL || ef->strsz == 0) + goto out; + COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets)); + COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains)); + ef->buckets = ef->hashtab + 2; + ef->chains = ef->buckets + ef->nbuckets; + if (__elfN(parse_modmetadata)(fp, ef) == 0) goto out; - for (i = 0; i < ndp; i++) { - if (dp[i].d_tag == NULL) - break; - if (dp[i].d_tag != DT_NEEDED) - continue; - j = dp[i].d_un.d_ptr; - if (j < 1 || j > (strsz - 2)) - continue; /* bad symbol name index */ - s = strdupout((vm_offset_t)&strtab[j]); - mod_addmetadata(mp, MODINFOMD_DEPLIST, strlen(s) + 1, s); - free(s); - } + if (ef->kernel) /* kernel must not depend on anything */ + goto out; out: if (dp) @@ -486,3 +537,205 @@ out: free(shdr); return ret; } + +static char invalid_name[] = "bad"; + +char * +fake_modname(const char *name) +{ + const char *sp, *ep; + char *fp; + size_t len; + + sp = strrchr(name, '/'); + if (sp) + sp++; + else + sp = name; + ep = strrchr(name, '.'); + if (ep) { + if (ep == name) { + sp = invalid_name; + ep = invalid_name + sizeof(invalid_name) - 1; + } + } else + ep = name + strlen(name); + len = ep - sp; + fp = malloc(len + 1); + if (fp == NULL) + return NULL; + memcpy(fp, sp, len); + fp[len] = '\0'; + return fp; +} + +#if defined(__i386__) && __ELF_WORD_SIZE == 64 +struct mod_metadata64 { + int md_version; /* structure version MDTV_* */ + int md_type; /* type of entry MDT_* */ + u_int64_t md_data; /* specific data */ + u_int64_t md_cval; /* common string label */ +}; +#endif + +int +__elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef) +{ + struct mod_metadata md; +#if defined(__i386__) && __ELF_WORD_SIZE == 64 + struct mod_metadata64 md64; +#endif + struct mod_depend *mdepend; + struct mod_version mver; + Elf_Sym sym; + char *s; + int modcnt, minfolen; + Elf_Addr v, p, p_stop; + + if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0) + return ENOENT; + p = sym.st_value + ef->off; + if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0) + return ENOENT; + p_stop = sym.st_value + ef->off; + + modcnt = 0; + while (p < p_stop) { + COPYOUT(p, &v, sizeof(v)); +#ifdef __sparc64__ + __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v)); +#else + v += ef->off; +#endif +#if defined(__i386__) && __ELF_WORD_SIZE == 64 + COPYOUT(v, &md64, sizeof(md64)); + md.md_version = md64.md_version; + md.md_type = md64.md_type; + md.md_cval = (const char *)(uintptr_t)(md64.md_cval + ef->off); + md.md_data = (void *)(uintptr_t)(md64.md_data + ef->off); +#else + COPYOUT(v, &md, sizeof(md)); +#ifdef __sparc64__ + __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md)); +#else + md.md_cval += ef->off; + md.md_data += ef->off; +#endif +#endif + p += sizeof(Elf_Addr); + switch(md.md_type) { + case MDT_DEPEND: + if (ef->kernel) /* kernel must not depend on anything */ + break; + s = strdupout((vm_offset_t)md.md_cval); + minfolen = sizeof(*mdepend) + strlen(s) + 1; + mdepend = malloc(minfolen); + if (mdepend == NULL) + return ENOMEM; + COPYOUT((vm_offset_t)md.md_data, mdepend, sizeof(*mdepend)); + strcpy((char*)(mdepend + 1), s); + free(s); + file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen, mdepend); + free(mdepend); + break; + case MDT_VERSION: + s = strdupout((vm_offset_t)md.md_cval); + COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver)); + file_addmodule(fp, s, mver.mv_version, NULL); + free(s); + modcnt++; + break; + } + } + if (modcnt == 0) { + s = fake_modname(fp->f_name); + file_addmodule(fp, s, 1, NULL); + free(s); + } + return 0; +} + +static unsigned long +elf_hash(const char *name) +{ + const unsigned char *p = (const unsigned char *) name; + unsigned long h = 0; + unsigned long g; + + while (*p != '\0') { + h = (h << 4) + *p++; + if ((g = h & 0xf0000000) != 0) + h ^= g >> 24; + h &= ~g; + } + return h; +} + +static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) "_lookup_symbol: corrupt symbol table\n"; +int +__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef, const char* name, + Elf_Sym *symp) +{ + Elf_Hashelt symnum; + Elf_Sym sym; + char *strp; + unsigned long hash; + + hash = elf_hash(name); + COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum)); + + while (symnum != STN_UNDEF) { + if (symnum >= ef->nchains) { + printf(__elfN(bad_symtable)); + return ENOENT; + } + + COPYOUT(ef->symtab + symnum, &sym, sizeof(sym)); + if (sym.st_name == 0) { + printf(__elfN(bad_symtable)); + return ENOENT; + } + + strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name)); + if (strcmp(name, strp) == 0) { + free(strp); + if (sym.st_shndx != SHN_UNDEF || + (sym.st_value != 0 && + ELF_ST_TYPE(sym.st_info) == STT_FUNC)) { + *symp = sym; + return 0; + } + return ENOENT; + } + free(strp); + COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum)); + } + return ENOENT; +} + +#ifdef __sparc__ +/* + * Apply any intra-module relocations to the value. *p is the load address + * of the value and val/len is the value to be modified. This does NOT modify + * the image in-place, because this is done by kern_linker later on. + */ +static void +__elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, + void *p, void *val, size_t len) +{ + Elf_Addr off = (Elf_Addr)p - ef->off, word; + size_t n; + Elf_Rela r; + + for (n = 0; n < ef->relasz / sizeof(r); n++) { + COPYOUT(ef->rela + n, &r, sizeof(r)); + + if (r.r_offset >= off && r.r_offset < off + len && + ELF_R_TYPE(r.r_info) == R_SPARC_RELATIVE) { + word = ef->off + r.r_addend; + bcopy(&word, (char *)val + (r.r_offset - off), + sizeof(word)); + } + } +} +#endif diff --git a/sys/boot/common/load_elf32.c b/sys/boot/common/load_elf32.c new file mode 100644 index 0000000000..95387a665b --- /dev/null +++ b/sys/boot/common/load_elf32.c @@ -0,0 +1,8 @@ +/* + * $FreeBSD: src/sys/boot/common/load_elf32.c,v 1.2 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/load_elf32.c,v 1.1 2003/11/10 06:08:31 dillon Exp $ + */ + +#define __ELF_WORD_SIZE 32 + +#include "load_elf.c" diff --git a/sys/boot/common/load_elf64.c b/sys/boot/common/load_elf64.c new file mode 100644 index 0000000000..ce0d1d67d8 --- /dev/null +++ b/sys/boot/common/load_elf64.c @@ -0,0 +1,8 @@ +/* + * $FreeBSD: src/sys/boot/common/load_elf64.c,v 1.2 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/load_elf64.c,v 1.1 2003/11/10 06:08:31 dillon Exp $ + */ + +#define __ELF_WORD_SIZE 64 + +#include "load_elf.c" diff --git a/sys/boot/common/loader.8 b/sys/boot/common/loader.8 index 38dd72e9d4..4106adf730 100644 --- a/sys/boot/common/loader.8 +++ b/sys/boot/common/loader.8 @@ -22,8 +22,8 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/sys/boot/common/loader.8,v 1.18.2.15 2003/05/10 23:40:09 murray Exp $ -.\" $DragonFly: src/sys/boot/common/loader.8,v 1.3 2003/10/02 19:24:10 dillon Exp $ +.\" $FreeBSD: src/sys/boot/common/loader.8,v 1.57 2003/06/29 20:57:55 brueffer Exp $ +.\" $DragonFly: src/sys/boot/common/loader.8,v 1.4 2003/11/10 06:08:31 dillon Exp $ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. @@ -58,7 +58,7 @@ commands" for historical reasons. The main drive behind these commands is user-friendliness. The bigger component is an .Tn ANS -Forth compatible Forth interpreter based on ficl, by +Forth compatible Forth interpreter based on FICL, by .An John Sadler . .Pp During initialization, @@ -79,7 +79,7 @@ Next, .Tn FICL is initialized, the builtin words are added to its vocabulary, and .Pa /boot/boot.4th -will be processed if it exists. +is processed if it exists. No disk switching is possible while that file is being read. The inner interpreter .Nm @@ -94,7 +94,7 @@ After that, .Pa /boot/loader.rc is processed if available, and, failing that, .Pa /boot/boot.conf -will be read for historical reasons. +is read for historical reasons. These files are processed through the .Ic include command, which reads all of them into memory before processing them, @@ -115,8 +115,9 @@ will be set and .Nm will engage interactive mode. .Sh BUILTIN COMMANDS -.Nm Loader Ns 's -builtin commands take its parameters from the command line. +In +.Nm , +builtin commands take parameters from the command line. Presently, the only way to call them from a script is by using .Pa evaluate @@ -310,6 +311,12 @@ Some options may require a value, while others define behavior just by being set. Both types of builtin variables are described below. .Bl -tag -width bootfile +.It Va acpi_load +Unset this to disable automatic loading of the ACPI module. +See also +.Va hint.acpi.0.disabled +in +.Xr device.hints 5 . .It Va autoboot_delay Number of seconds .Ic autoboot @@ -369,7 +376,7 @@ Define the number of lines on the screen, to be used by the pager. Sets the list of directories which will be searched for modules named in a load command or implicitly required by a dependency. The default value for this variable is -.Dq Li /;/boot;/modules . +.Dq Li /boot/kernel;/boot/modules . .It Va num_ide_disks Sets the number of IDE disks as a workaround for some problems in finding the root disk at boot. @@ -389,7 +396,7 @@ be forced by setting this variable. .It Va rootdev By default the value of .Va currdev -is used to set the root filesystem +is used to set the root file system when the kernel is booted. This can be overridden by setting .Va rootdev @@ -406,6 +413,26 @@ MIB variable. Other variables are used to override kernel tunable parameters. The following tunables are available: .Bl -tag -width Va +.It Va hw.physmem +Limit the amount of physical memory the system will use. +By default the size is in bytes, but the +.Cm k , K , m , M , g +and +.Cm G +suffixes +are also accepted and indicate kilobytes, megabytes and gigabytes +respectively. +An invalid suffix will result in the variable being ignored by the +kernel. +.It Va hw.pci.enable_io_modes +Enable PCI resources which are left off by some BIOSes or are not +enabled correctly by the device driver. +Tunable value set to ON (1) by default, but this may cause problems +with some peripherals. +.It Va hw.pci.allow_unsupported_io_range +Allow the PCI bridge to pass through an unsupported memory range +assigned by the BIOS. +Tunable value set to OFF (0) by default. .It Va kern.maxusers Set the size of a number of statically allocated system tables; see .Xr tuning 7 @@ -419,10 +446,15 @@ The value cannot be set below the default determined when the kernel was compiled. Modifies .Va NMBCLUSTERS . +.It Va kern.ipc.nsfbufs +Set the number of +.Xr sendfile 2 +buffers to be allocated. +Overrides +.Dv NSFBUFS . .It Va kern.vm.kmem.size Sets the size of kernel memory (bytes). -This overrides completely the value -determined when the kernel was compiled. +This overrides the value determined when the kernel was compiled. Modifies .Va VM_KMEM_SIZE . .It Va kern.maxswzone @@ -460,22 +492,13 @@ Note that the NBUF parameter will override this limit. Modifies .Va VM_BCACHE_SIZE_MAX . -.It Va machdep.pccard.pcic_irq -Overrides the IRQ normally assigned to a PCCARD controller. -Typically the first available interrupt will be allocated, -which may conflict with other hardware. -If this value is set to 0, -an interrupt will not be assigned -and the controller will operate in polled mode only. +.It Va machdep.disable_mtrrs +Disable the use of i686 MTRRs (x86 only). .It Va net.inet.tcp.tcbhashsize Overrides the compile-time set value of .Va TCBHASHSIZE or the preset default of 512. Must be a power of 2. -.It Va hw.physmem -Overrides the amount of physical memory recognized by the system. -May be specified in units of 'g'igabytes, 'm'egabytes, or 'k'ilobytes. -This variable is typically only used for debugging purposes. .El .Ss BUILTIN PARSER When a builtin command is executed, the rest of the line is taken @@ -655,9 +678,20 @@ Reads a single character from a file. .It Ic fload Pq Ar fd -- Processes a file .Em fd . -.It Ic fopen Pq Ar addr len -- fd +.It Ic fopen Pq Ar addr len mode Li -- Ar fd Opens a file. -Returns a file descriptor, or -1 in case of failure. +Returns a file descriptor, or \-1 in case of failure. +The +.Ar mode +parameter selects whether the file is to be opened for read access, write +access, or both. +The constants +.Dv O_RDONLY , O_WRONLY , +and +.Dv O_RDWR +are defined in +.Pa /boot/support.4th , +indicating read only, write only, and read-write access, respectively. .It Xo .Ic fread .Pq Ar fd addr len -- len' @@ -844,11 +878,13 @@ from the Programming-Tools extension word set, Providing the Search-Order extensions word set. .Ef .Sh HISTORY +The .Nm first appeared in .Fx 3.1 . .Sh AUTHORS .An -nosplit +The .Nm was written by .An Michael Smith Aq msmith@FreeBSD.org . diff --git a/sys/boot/common/ls.c b/sys/boot/common/ls.c index eb47d96a96..ca0eac3efc 100644 --- a/sys/boot/common/ls.c +++ b/sys/boot/common/ls.c @@ -1,10 +1,8 @@ /* - * $FreeBSD: src/sys/boot/common/ls.c,v 1.8.2.2 2000/07/07 00:09:45 obrien Exp $ - * $DragonFly: src/sys/boot/common/ls.c,v 1.3 2003/08/07 21:16:44 dillon Exp $ - * From: $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $ + * $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $ */ -/* +/*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * Copyright (c) 1996 @@ -37,12 +35,14 @@ * 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. + * + * $FreeBSD: src/sys/boot/common/ls.c,v 1.11 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/ls.c,v 1.4 2003/11/10 06:08:31 dillon Exp $ */ - #include -#include -#include +#include +#include #include #include diff --git a/sys/boot/common/merge_help.awk b/sys/boot/common/merge_help.awk index 2f9e8065f0..a5dd388f43 100644 --- a/sys/boot/common/merge_help.awk +++ b/sys/boot/common/merge_help.awk @@ -1,7 +1,7 @@ #!/usr/bin/awk -f # -# $FreeBSD: src/sys/boot/common/merge_help.awk,v 1.2 1999/08/28 00:39:50 peter Exp $ -# $DragonFly: src/sys/boot/common/merge_help.awk,v 1.2 2003/06/17 04:28:16 dillon Exp $ +# $FreeBSD: src/sys/boot/common/merge_help.awk,v 1.5 2001/11/07 17:53:25 fenner Exp $ +# $DragonFly: src/sys/boot/common/merge_help.awk,v 1.3 2003/11/10 06:08:31 dillon Exp $ # # Merge two boot loader help files for FreeBSD 3.0 # Joe Abley @@ -9,7 +9,7 @@ BEGIN \ { state = 0; - first = 0; + first = -1; ind = 0; } diff --git a/sys/boot/common/misc.c b/sys/boot/common/misc.c index 79cb755028..68d559204a 100644 --- a/sys/boot/common/misc.c +++ b/sys/boot/common/misc.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/misc.c,v 1.6.2.1 2000/07/06 00:34:02 ps Exp $ - * $DragonFly: src/sys/boot/common/misc.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/common/misc.c,v 1.8 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/misc.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ #include diff --git a/sys/boot/common/module.c b/sys/boot/common/module.c index 4348ea9551..70e2a87996 100644 --- a/sys/boot/common/module.c +++ b/sys/boot/common/module.c @@ -23,34 +23,61 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/module.c,v 1.13.2.4 2002/12/19 12:41:10 thomas Exp $ - * $DragonFly: src/sys/boot/common/module.c,v 1.2 2003/06/17 04:28:17 dillon Exp $ + * $FreeBSD: src/sys/boot/common/module.c,v 1.25 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/module.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ /* - * module function dispatcher, support, etc. + * file/module function dispatcher, support, etc. */ #include #include #include #include +#include +#include #include "bootstrap.h" -static int mod_loadmodule(char *name, int argc, char *argv[], struct loaded_module **mpp); -static int file_load_dependancies(struct loaded_module *base_file); -static char *mod_searchfile(char *name); -static char *mod_searchmodule(char *name); -static void mod_append(struct loaded_module *mp); -static struct module_metadata *metadata_next(struct module_metadata *md, int type); +#define MDIR_REMOVED 0x0001 +#define MDIR_NOHINTS 0x0002 + +struct moduledir { + char *d_path; /* path of modules directory */ + u_char *d_hints; /* content of linker.hints file */ + int d_hintsz; /* size of hints data */ + int d_flags; + STAILQ_ENTRY(moduledir) d_link; +}; + +static int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result); +static int file_loadraw(char *type, char *name); +static int file_load_dependencies(struct preloaded_file *base_mod); +static char * file_search(const char *name, char **extlist); +static struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo); +static int file_havepath(const char *name); +static char *mod_searchmodule(char *name, struct mod_depend *verinfo); +static void file_insert_tail(struct preloaded_file *mp); +struct file_metadata* metadata_next(struct file_metadata *base_mp, int type); +static void moduledir_readhints(struct moduledir *mdp); +static void moduledir_rebuild(void); /* load address should be tweaked by first module loaded (kernel) */ static vm_offset_t loadaddr = 0; -static const char *default_searchpath ="/;/boot;/modules"; +static const char *default_searchpath ="/boot/kernel;/boot/modules"; + +static STAILQ_HEAD(, moduledir) moduledir_list = STAILQ_HEAD_INITIALIZER(moduledir_list); + +struct preloaded_file *preloaded_files = NULL; + +static char *kld_ext_list[] = { + ".ko", + "", + NULL +}; -struct loaded_module *loaded_modules = NULL; /* * load an object, either a disk file or code module. @@ -70,9 +97,9 @@ static int command_load(int argc, char *argv[]) { char *typestr; - int dofile, ch, error; + int dofile, dokld, ch, error; - dofile = 0; + dokld = dofile = 0; optind = 1; optreset = 1; typestr = NULL; @@ -80,8 +107,11 @@ command_load(int argc, char *argv[]) command_errmsg = "no filename specified"; return(CMD_ERROR); } - while ((ch = getopt(argc, argv, "t:")) != -1) { + while ((ch = getopt(argc, argv, "kt:")) != -1) { switch(ch) { + case 'k': + dokld = 1; + break; case 't': typestr = optarg; dofile = 1; @@ -103,13 +133,21 @@ command_load(int argc, char *argv[]) command_errmsg = "invalid load type"; return(CMD_ERROR); } - return(mod_loadobj(typestr, argv[1])); + return(file_loadraw(typestr, argv[1])); + } + /* + * Do we have explicit KLD load ? + */ + if (dokld || file_havepath(argv[1])) { + error = mod_loadkld(argv[1], argc - 2, argv + 2); + if (error == EEXIST) + sprintf(command_errbuf, "warning: KLD '%s' already loaded", argv[1]); + return (error == 0 ? CMD_OK : CMD_ERROR); } - /* * Looks like a request for a module. */ - error = mod_load(argv[1], argc - 2, argv + 2); + error = mod_load(argv[1], NULL, argc - 2, argv + 2); if (error == EEXIST) sprintf(command_errbuf, "warning: module '%s' already loaded", argv[1]); return (error == 0 ? CMD_OK : CMD_ERROR); @@ -120,14 +158,15 @@ COMMAND_SET(unload, "unload", "unload all modules", command_unload); static int command_unload(int argc, char *argv[]) { - struct loaded_module *mp; + struct preloaded_file *fp; - while (loaded_modules != NULL) { - mp = loaded_modules; - loaded_modules = loaded_modules->m_next; - mod_discard(mp); + while (preloaded_files != NULL) { + fp = preloaded_files; + preloaded_files = preloaded_files->f_next; + file_discard(fp); } loadaddr = 0; + unsetenv("kernelname"); return(CMD_OK); } @@ -136,8 +175,9 @@ COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod); static int command_lsmod(int argc, char *argv[]) { - struct loaded_module *am; - struct module_metadata *md; + struct preloaded_file *fp; + struct kernel_module *mp; + struct file_metadata *md; char lbuf[80]; int ch, verbose; @@ -157,90 +197,130 @@ command_lsmod(int argc, char *argv[]) } pager_open(); - for (am = loaded_modules; (am != NULL); am = am->m_next) { + for (fp = preloaded_files; fp; fp = fp->f_next) { sprintf(lbuf, " %p: %s (%s, 0x%lx)\n", - (void *) am->m_addr, am->m_name, am->m_type, (long) am->m_size); + (void *) fp->f_addr, fp->f_name, fp->f_type, (long) fp->f_size); pager_output(lbuf); - if (am->m_args != NULL) { + if (fp->f_args != NULL) { pager_output(" args: "); - pager_output(am->m_args); + pager_output(fp->f_args); + pager_output("\n"); + } + if (fp->f_modules) { + pager_output(" modules: "); + for (mp = fp->f_modules; mp; mp = mp->m_next) { + sprintf(lbuf, "%s.%d ", mp->m_name, mp->m_version); + pager_output(lbuf); + } pager_output("\n"); } - if (verbose) + if (verbose) { /* XXX could add some formatting smarts here to display some better */ - for (md = am->m_metadata; md != NULL; md = md->md_next) { + for (md = fp->f_metadata; md != NULL; md = md->md_next) { sprintf(lbuf, " 0x%04x, 0x%lx\n", md->md_type, (long) md->md_size); pager_output(lbuf); } + } } pager_close(); return(CMD_OK); } /* - * We've been asked to load (name) and give it (argc),(argv). - * Start by trying to load it, and then attempt to load all of its - * dependancies. If we fail at any point, throw them all away and - * fail the entire load. - * - * XXX if a depended-on module requires arguments, it must be loaded - * explicitly first. + * File level interface, functions file_* */ int -mod_load(char *name, int argc, char *argv[]) +file_load(char *filename, vm_offset_t dest, struct preloaded_file **result) { - struct loaded_module *last_mod, *base_mod, *mp; - int error; - - /* remember previous last module on chain */ - for (last_mod = loaded_modules; - (last_mod != NULL) && (last_mod->m_next != NULL); - last_mod = last_mod->m_next) - ; - - /* - * Load the first module; note that it's the only one that gets - * arguments explicitly. - */ - error = mod_loadmodule(name, argc, argv, &base_mod); - if (error) - return (error); + struct preloaded_file *fp; + int error; + int i; + + error = EFTYPE; + for (i = 0, fp = NULL; file_formats[i] && fp == NULL; i++) { + error = (file_formats[i]->l_load)(filename, loadaddr, &fp); + if (error == 0) { + fp->f_loader = i; /* remember the loader */ + *result = fp; + break; + } + if (error == EFTYPE) + continue; /* Unknown to this handler? */ + if (error) { + sprintf(command_errbuf, "can't load file '%s': %s", + filename, strerror(error)); + break; + } + } + return (error); +} - error = file_load_dependancies(base_mod); +static int +file_load_dependencies(struct preloaded_file *base_file) { + struct file_metadata *md; + struct preloaded_file *fp; + struct mod_depend *verinfo; + struct kernel_module *mp; + char *dmodname; + int error; + + md = file_findmetadata(base_file, MODINFOMD_DEPLIST); + if (md == NULL) + return (0); + error = 0; + do { + verinfo = (struct mod_depend*)md->md_data; + dmodname = (char *)(verinfo + 1); + if (file_findmodule(NULL, dmodname, verinfo) == NULL) { + printf("loading required module '%s'\n", dmodname); + error = mod_load(dmodname, verinfo, 0, NULL); + if (error) + break; + /* + * If module loaded via kld name which isn't listed + * in the linker.hints file, we should check if it have + * required version. + */ + mp = file_findmodule(NULL, dmodname, verinfo); + if (mp == NULL) { + sprintf(command_errbuf, "module '%s' exists but with wrong version", + dmodname); + error = ENOENT; + break; + } + } + md = metadata_next(md, MODINFOMD_DEPLIST); + } while (md); if (!error) return (0); - /* Load failed; discard everything */ - last_mod->m_next = NULL; - loadaddr = last_mod->m_addr + last_mod->m_size; - while (base_mod != NULL) { - mp = base_mod; - base_mod = base_mod->m_next; - mod_discard(mp); + while (base_file != NULL) { + fp = base_file; + base_file = base_file->f_next; + file_discard(fp); } return (error); } - /* * We've been asked to load (name) as (type), so just suck it in, * no arguments or anything. */ int -mod_loadobj(char *type, char *name) +file_loadraw(char *type, char *name) { - struct loaded_module *mp; + struct preloaded_file *fp; char *cp; int fd, got; vm_offset_t laddr; /* We can't load first */ - if ((mod_findmodule(NULL, NULL)) == NULL) { + if ((file_findfile(NULL, NULL)) == NULL) { command_errmsg = "can't load file before kernel"; return(CMD_ERROR); } /* locate the file on the load path */ - cp = mod_searchfile(name); + cp = file_search(name, NULL); if (cp == NULL) { sprintf(command_errbuf, "can't find '%s'", name); return(CMD_ERROR); @@ -269,168 +349,205 @@ mod_loadobj(char *type, char *name) } /* Looks OK so far; create & populate control structure */ - mp = malloc(sizeof(struct loaded_module)); - mp->m_name = name; - mp->m_type = strdup(type); - mp->m_args = NULL; - mp->m_metadata = NULL; - mp->m_loader = -1; - mp->m_addr = loadaddr; - mp->m_size = laddr - loadaddr; + fp = file_alloc(); + fp->f_name = name; + fp->f_type = strdup(type); + fp->f_args = NULL; + fp->f_metadata = NULL; + fp->f_loader = -1; + fp->f_addr = loadaddr; + fp->f_size = laddr - loadaddr; /* recognise space consumption */ loadaddr = laddr; - /* Add to the list of loaded modules */ - mod_append(mp); + /* Add to the list of loaded files */ + file_insert_tail(fp); close(fd); return(CMD_OK); } /* - * Load the module (name), pass it (argc),(argv). - * Don't do any dependancy checking. + * Load the module (name), pass it (argc),(argv), add container file + * to the list of loaded files. + * If module is already loaded just assign new argc/argv. */ -static int -mod_loadmodule(char *name, int argc, char *argv[], struct loaded_module **mpp) +int +mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[]) { - struct loaded_module *mp; - int i, err; - char *cp; + struct kernel_module *mp; + int err; + char *filename; - /* locate the module on the search path */ - cp = mod_searchmodule(name); - if (cp == NULL) { - sprintf(command_errbuf, "can't find '%s'", name); - return (ENOENT); + if (file_havepath(modname)) { + printf("Warning: mod_load() called instead of mod_loadkld() for module '%s'\n", modname); + return (mod_loadkld(modname, argc, argv)); } - name = cp; - - cp = strrchr(name, '/'); - if (cp) - cp++; - else - cp = name; /* see if module is already loaded */ - mp = mod_findmodule(cp, NULL); + mp = file_findmodule(NULL, modname, verinfo); if (mp) { - *mpp = mp; - return (EEXIST); +#ifdef moduleargs + if (mp->m_args) + free(mp->m_args); + mp->m_args = unargv(argc, argv); +#endif + sprintf(command_errbuf, "warning: module '%s' already loaded", mp->m_name); + return (0); } - - err = 0; - for (i = 0, mp = NULL; (module_formats[i] != NULL) && (mp == NULL); i++) { - if ((err = (module_formats[i]->l_load)(name, loadaddr, &mp)) != 0) { - - /* Unknown to this handler? */ - if (err == EFTYPE) - continue; - - /* Fatal error */ - sprintf(command_errbuf, "can't load module '%s': %s", name, strerror(err)); - free(name); - return (err); - } else { - - /* Load was OK, set args */ - mp->m_args = unargv(argc, argv); - - /* where can we put the next one? */ - loadaddr = mp->m_addr + mp->m_size; - - /* remember the loader */ - mp->m_loader = i; - - /* Add to the list of loaded modules */ - mod_append(mp); - *mpp = mp; - - break; - } + /* locate file with the module on the search path */ + filename = mod_searchmodule(modname, verinfo); + if (filename == NULL) { + sprintf(command_errbuf, "can't find '%s'", modname); + return (ENOENT); } - if (err == EFTYPE) - sprintf(command_errbuf, "don't know how to load module '%s'", name); - free(name); + err = mod_loadkld(filename, argc, argv); return (err); } -static int -file_load_dependancies(struct loaded_module *base_file) +/* + * Load specified KLD. If path is omitted, then try to locate it via + * search path. + */ +int +mod_loadkld(const char *kldname, int argc, char *argv[]) { - struct module_metadata *md; - char *dmodname; - int error; + struct preloaded_file *fp, *last_file; + int err; + char *filename; - md = mod_findmetadata(base_file, MODINFOMD_DEPLIST); - if (md == NULL) + /* + * Get fully qualified KLD name + */ + filename = file_search(kldname, kld_ext_list); + if (filename == NULL) { + sprintf(command_errbuf, "can't find '%s'", kldname); + return (ENOENT); + } + /* + * Check if KLD already loaded + */ + fp = file_findfile(filename, NULL); + if (fp) { + sprintf(command_errbuf, "warning: KLD '%s' already loaded", filename); + free(filename); return (0); - error = 0; + } + for (last_file = preloaded_files; + last_file != NULL && last_file->f_next != NULL; + last_file = last_file->f_next) + ; + do { - dmodname = (char *)md->md_data; - if (mod_findmodule(NULL, dmodname) == NULL) { - printf("loading required module '%s'\n", dmodname); - error = mod_load(dmodname, 0, NULL); - if (error == EEXIST) - error = 0; - if (error != 0) - break; + err = file_load(filename, loadaddr, &fp); + if (err) + break; + fp->f_args = unargv(argc, argv); + loadaddr = fp->f_addr + fp->f_size; + file_insert_tail(fp); /* Add to the list of loaded files */ + if (file_load_dependencies(fp) != 0) { + err = ENOENT; + last_file->f_next = NULL; + loadaddr = last_file->f_addr + last_file->f_size; + fp = NULL; + break; } - md = metadata_next(md, MODINFOMD_DEPLIST); - } while (md); - return (error); + } while(0); + if (err == EFTYPE) + sprintf(command_errbuf, "don't know how to load module '%s'", filename); + if (err && fp) + file_discard(fp); + free(filename); + return (err); } /* - * Find a module matching (name) and (type). + * Find a file matching (name) and (type). * NULL may be passed as a wildcard to either. */ -struct loaded_module * -mod_findmodule(char *name, char *type) +struct preloaded_file * +file_findfile(char *name, char *type) { - struct loaded_module *mp; - - for (mp = loaded_modules; mp != NULL; mp = mp->m_next) { - if (((name == NULL) || !strcmp(name, mp->m_name)) && - ((type == NULL) || !strcmp(type, mp->m_type))) + struct preloaded_file *fp; + + for (fp = preloaded_files; fp != NULL; fp = fp->f_next) { + if (((name == NULL) || !strcmp(name, fp->f_name)) && + ((type == NULL) || !strcmp(type, fp->f_type))) break; } - return(mp); + return (fp); } +/* + * Find a module matching (name) inside of given file. + * NULL may be passed as a wildcard. + */ +struct kernel_module * +file_findmodule(struct preloaded_file *fp, char *modname, + struct mod_depend *verinfo) +{ + struct kernel_module *mp, *best; + int bestver, mver; + + if (fp == NULL) { + for (fp = preloaded_files; fp; fp = fp->f_next) { + mp = file_findmodule(fp, modname, verinfo); + if (mp) + return (mp); + } + return (NULL); + } + best = NULL; + bestver = 0; + for (mp = fp->f_modules; mp; mp = mp->m_next) { + if (strcmp(modname, mp->m_name) == 0) { + if (verinfo == NULL) + return (mp); + mver = mp->m_version; + if (mver == verinfo->md_ver_preferred) + return (mp); + if (mver >= verinfo->md_ver_minimum && + mver <= verinfo->md_ver_maximum && + mver > bestver) { + best = mp; + bestver = mver; + } + } + } + return (best); +} /* * Make a copy of (size) bytes of data from (p), and associate them as * metadata of (type) to the module (mp). */ void -mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p) +file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p) { - struct module_metadata *md; + struct file_metadata *md; - md = malloc(sizeof(struct module_metadata) + size); + md = malloc(sizeof(struct file_metadata) - sizeof(md->md_data) + size); md->md_size = size; md->md_type = type; bcopy(p, md->md_data, size); - md->md_next = mp->m_metadata; - mp->m_metadata = md; + md->md_next = fp->f_metadata; + fp->f_metadata = md; } /* - * Find a metadata object of (type) associated with the module - * (mp) + * Find a metadata object of (type) associated with the file (fp) */ -struct module_metadata * -mod_findmetadata(struct loaded_module *mp, int type) +struct file_metadata * +file_findmetadata(struct preloaded_file *fp, int type) { - struct module_metadata *md; + struct file_metadata *md; - for (md = mp->m_metadata; md != NULL; md = md->md_next) + for (md = fp->f_metadata; md != NULL; md = md->md_next) if (md->md_type == type) break; return(md); } -struct module_metadata * -metadata_next(struct module_metadata *md, int type) +struct file_metadata * +metadata_next(struct file_metadata *md, int type) { if (md == NULL) return (NULL); @@ -440,6 +557,57 @@ metadata_next(struct module_metadata *md, int type) return (md); } +static char *emptyextlist[] = { "", NULL }; + +/* + * Check if the given file is in place and return full path to it. + */ +static char * +file_lookup(const char *path, const char *name, int namelen, char **extlist) +{ + struct stat st; + char *result, *cp, **cpp; + int pathlen, extlen, len; + + pathlen = strlen(path); + extlen = 0; + if (extlist == NULL) + extlist = emptyextlist; + for (cpp = extlist; *cpp; cpp++) { + len = strlen(*cpp); + if (len > extlen) + extlen = len; + } + result = malloc(pathlen + namelen + extlen + 2); + if (result == NULL) + return (NULL); + bcopy(path, result, pathlen); + if (pathlen > 0 && result[pathlen - 1] != '/') + result[pathlen++] = '/'; + cp = result + pathlen; + bcopy(name, cp, namelen); + cp += namelen; + for (cpp = extlist; *cpp; cpp++) { + strcpy(cp, *cpp); + if (stat(result, &st) == 0 && S_ISREG(st.st_mode)) + return result; + } + free(result); + return NULL; +} + +/* + * Check if file name have any qualifiers + */ +static int +file_havepath(const char *name) +{ + const char *cp; + + archsw.arch_getdev(NULL, name, &cp); + return (cp != name || strchr(name, '/') != NULL); +} + /* * Attempt to find the file (name) on the module searchpath. * If (name) is qualified in any way, we simply check it and @@ -451,136 +619,343 @@ metadata_next(struct module_metadata *md, int type) * it internally. */ static char * -mod_searchfile(char *name) +file_search(const char *name, char **extlist) { - char *result; - char *path, *sp; - const char *cp; + struct moduledir *mdp; struct stat sb; + char *result; + int namelen; /* Don't look for nothing */ if (name == NULL) - return(name); + return(NULL); if (*name == 0) return(strdup(name)); - /* - * See if there's a device on the front, or a directory name. - */ - archsw.arch_getdev(NULL, name, &cp); - if ((cp != name) || (strchr(name, '/') != NULL)) { + if (file_havepath(name)) { /* Qualified, so just see if it exists */ if (stat(name, &sb) == 0) return(strdup(name)); return(NULL); } - - /* - * Get the module path - */ - if ((cp = getenv("module_path")) == NULL) - cp = default_searchpath; - sp = path = strdup(cp); - - /* - * Traverse the path, splitting off ';'-delimited components. - */ + moduledir_rebuild(); result = NULL; - while((cp = strsep(&path, ";")) != NULL) { - result = malloc(strlen(cp) + strlen(name) + 5); - strcpy(result, cp); - if (cp[strlen(cp) - 1] != '/') - strcat(result, "/"); - strcat(result, name); -/* printf("search '%s'\n", result); */ - if ((stat(result, &sb) == 0) && - S_ISREG(sb.st_mode)) + namelen = strlen(name); + STAILQ_FOREACH(mdp, &moduledir_list, d_link) { + result = file_lookup(mdp->d_path, name, namelen, extlist); + if (result) break; - free(result); - result = NULL; } - free(sp); return(result); } +#define INT_ALIGN(base, ptr) ptr = \ + (base) + (((ptr) - (base) + sizeof(int) - 1) & ~(sizeof(int) - 1)) + +static char * +mod_search_hints(struct moduledir *mdp, const char *modname, + struct mod_depend *verinfo) +{ + u_char *cp, *recptr, *bufend, *best; + char *result; + int *intp, bestver, blen, clen, found, ival, modnamelen, reclen; + + moduledir_readhints(mdp); + modnamelen = strlen(modname); + found = 0; + result = NULL; + bestver = 0; + if (mdp->d_hints == NULL) + goto bad; + recptr = mdp->d_hints; + bufend = recptr + mdp->d_hintsz; + clen = blen = 0; + best = cp = NULL; + while (recptr < bufend && !found) { + intp = (int*)recptr; + reclen = *intp++; + ival = *intp++; + cp = (char*)intp; + switch (ival) { + case MDT_VERSION: + clen = *cp++; + if (clen != modnamelen || bcmp(cp, modname, clen) != 0) + break; + cp += clen; + INT_ALIGN(mdp->d_hints, cp); + ival = *(int*)cp; + cp += sizeof(int); + clen = *cp++; + if (verinfo == NULL || ival == verinfo->md_ver_preferred) { + found = 1; + break; + } + if (ival >= verinfo->md_ver_minimum && + ival <= verinfo->md_ver_maximum && + ival > bestver) { + bestver = ival; + best = cp; + blen = clen; + } + break; + default: + break; + } + recptr += reclen + sizeof(int); + } + /* + * Finally check if KLD is in the place + */ + if (found) + result = file_lookup(mdp->d_path, cp, clen, NULL); + else if (best) + result = file_lookup(mdp->d_path, best, blen, NULL); +bad: + /* + * If nothing found or hints is absent - fallback to the old way + * by using "kldname[.ko]" as module name. + */ + if (!found && !bestver && result == NULL) + result = file_lookup(mdp->d_path, modname, modnamelen, kld_ext_list); + return result; +} + /* * Attempt to locate the file containing the module (name) */ static char * -mod_searchmodule(char *name) +mod_searchmodule(char *name, struct mod_depend *verinfo) { - char *tn, *result; - - /* Look for (name).ko */ - tn = malloc(strlen(name) + 3 + 1); - strcpy(tn, name); - strcat(tn, ".ko"); - result = mod_searchfile(tn); - free(tn); - /* Look for just (name) (useful for finding kernels) */ - if (result == NULL) - result = mod_searchfile(name); + struct moduledir *mdp; + char *result; + + moduledir_rebuild(); + /* + * Now we ready to lookup module in the given directories + */ + result = NULL; + STAILQ_FOREACH(mdp, &moduledir_list, d_link) { + result = mod_search_hints(mdp, name, verinfo); + if (result) + break; + } return(result); } +int +file_addmodule(struct preloaded_file *fp, char *modname, int version, + struct kernel_module **newmp) +{ + struct kernel_module *mp; + struct mod_depend mdepend; + + bzero(&mdepend, sizeof(mdepend)); + mdepend.md_ver_preferred = version; + mp = file_findmodule(fp, modname, &mdepend); + if (mp) + return (EEXIST); + mp = malloc(sizeof(struct kernel_module)); + if (mp == NULL) + return (ENOMEM); + bzero(mp, sizeof(struct kernel_module)); + mp->m_name = strdup(modname); + mp->m_version = version; + mp->m_fp = fp; + mp->m_next = fp->f_modules; + fp->f_modules = mp; + if (newmp) + *newmp = mp; + return (0); +} /* - * Throw a module away + * Throw a file away */ void -mod_discard(struct loaded_module *mp) +file_discard(struct preloaded_file *fp) { - struct module_metadata *md; - - if (mp != NULL) { - while (mp->m_metadata != NULL) { - md = mp->m_metadata; - mp->m_metadata = mp->m_metadata->md_next; - free(md); - } - if (mp->m_name != NULL) - free(mp->m_name); - if (mp->m_type != NULL) - free(mp->m_type); - if (mp->m_args != NULL) - free(mp->m_args); - free(mp); + struct file_metadata *md, *md1; + struct kernel_module *mp, *mp1; + if (fp == NULL) + return; + md = fp->f_metadata; + while (md) { + md1 = md; + md = md->md_next; + free(md1); } + mp = fp->f_modules; + while (mp) { + if (mp->m_name) + free(mp->m_name); + mp1 = mp; + mp = mp->m_next; + free(mp1); + } + if (fp->f_name != NULL) + free(fp->f_name); + if (fp->f_type != NULL) + free(fp->f_type); + if (fp->f_args != NULL) + free(fp->f_args); + free(fp); } /* - * Allocate a new module; must be used instead of malloc() + * Allocate a new file; must be used instead of malloc() * to ensure safe initialisation. */ -struct loaded_module * -mod_allocmodule(void) +struct preloaded_file * +file_alloc(void) { - struct loaded_module *mp; + struct preloaded_file *fp; - if ((mp = malloc(sizeof(struct loaded_module))) != NULL) { - bzero(mp, sizeof(struct loaded_module)); + if ((fp = malloc(sizeof(struct preloaded_file))) != NULL) { + bzero(fp, sizeof(struct preloaded_file)); } - return(mp); + return (fp); } - /* * Add a module to the chain */ static void -mod_append(struct loaded_module *mp) +file_insert_tail(struct preloaded_file *fp) { - struct loaded_module *cm; + struct preloaded_file *cm; - /* Append to list of loaded modules */ - mp->m_next = NULL; - if (loaded_modules == NULL) { - loaded_modules = mp; + /* Append to list of loaded file */ + fp->f_next = NULL; + if (preloaded_files == NULL) { + preloaded_files = fp; } else { - for (cm = loaded_modules; cm->m_next != NULL; cm = cm->m_next) + for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) ; - cm->m_next = mp; + cm->f_next = fp; + } +} + +static char * +moduledir_fullpath(struct moduledir *mdp, const char *fname) +{ + char *cp; + + cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2); + if (cp == NULL) + return NULL; + strcpy(cp, mdp->d_path); + strcat(cp, "/"); + strcat(cp, fname); + return (cp); +} + +/* + * Read linker.hints file into memory performing some sanity checks. + */ +static void +moduledir_readhints(struct moduledir *mdp) +{ + struct stat st; + char *path; + int fd, size, version; + + if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS)) + return; + path = moduledir_fullpath(mdp, "linker.hints"); + if (stat(path, &st) != 0 || st.st_size < (sizeof(version) + sizeof(int)) || + st.st_size > 100 * 1024 || (fd = open(path, O_RDONLY)) < 0) { + free(path); + mdp->d_flags |= MDIR_NOHINTS; + return; + } + free(path); + size = read(fd, &version, sizeof(version)); + if (size != sizeof(version) || version != LINKER_HINTS_VERSION) + goto bad; + size = st.st_size - size; + mdp->d_hints = malloc(size); + if (mdp->d_hints == NULL) + goto bad; + if (read(fd, mdp->d_hints, size) != size) + goto bad; + mdp->d_hintsz = size; + close(fd); + return; +bad: + close(fd); + if (mdp->d_hints) { + free(mdp->d_hints); + mdp->d_hints = NULL; + } + mdp->d_flags |= MDIR_NOHINTS; + return; +} + +/* + * Extract directories from the ';' separated list, remove duplicates. + */ +static void +moduledir_rebuild(void) +{ + struct moduledir *mdp, *mtmp; + const char *path, *cp, *ep; + int cplen; + + path = getenv("module_path"); + if (path == NULL) + path = default_searchpath; + /* + * Rebuild list of module directories if it changed + */ + STAILQ_FOREACH(mdp, &moduledir_list, d_link) + mdp->d_flags |= MDIR_REMOVED; + + for (ep = path; *ep != 0; ep++) { + cp = ep; + for (; *ep != 0 && *ep != ';'; ep++) + ; + /* + * Ignore trailing slashes + */ + for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; cplen--) + ; + STAILQ_FOREACH(mdp, &moduledir_list, d_link) { + if (strlen(mdp->d_path) != cplen || bcmp(cp, mdp->d_path, cplen) != 0) + continue; + mdp->d_flags &= ~MDIR_REMOVED; + break; + } + if (mdp == NULL) { + mdp = malloc(sizeof(*mdp) + cplen + 1); + if (mdp == NULL) + return; + mdp->d_path = (char*)(mdp + 1); + bcopy(cp, mdp->d_path, cplen); + mdp->d_path[cplen] = 0; + mdp->d_hints = NULL; + mdp->d_flags = 0; + STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link); + } + if (*ep == 0) + break; + } + /* + * Delete unused directories if any + */ + mdp = STAILQ_FIRST(&moduledir_list); + while (mdp) { + if ((mdp->d_flags & MDIR_REMOVED) == 0) { + mdp = STAILQ_NEXT(mdp, d_link); + } else { + if (mdp->d_hints) + free(mdp->d_hints); + mtmp = mdp; + mdp = STAILQ_NEXT(mdp, d_link); + STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link); + free(mtmp); + } } + return; } diff --git a/sys/boot/common/newvers.sh b/sys/boot/common/newvers.sh index 30ac46cf16..fe47630783 100644 --- a/sys/boot/common/newvers.sh +++ b/sys/boot/common/newvers.sh @@ -1,8 +1,8 @@ #!/bin/sh - # -# $FreeBSD: src/sys/boot/common/newvers.sh,v 1.1.2.2 2001/03/05 13:08:45 ru Exp $ -# $DragonFly: src/sys/boot/common/newvers.sh,v 1.2 2003/06/17 04:28:17 dillon Exp $ -# $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $ +# $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $ +# $FreeBSD: src/sys/boot/common/newvers.sh,v 1.3 2001/03/02 16:52:12 ru Exp $ +# $DragonFly: src/sys/boot/common/newvers.sh,v 1.3 2003/11/10 06:08:31 dillon Exp $ # # Copyright (c) 1984, 1986, 1990, 1993 # The Regents of the University of California. All rights reserved. diff --git a/sys/boot/common/panic.c b/sys/boot/common/panic.c index a0fcbc4bfd..3daa822b40 100644 --- a/sys/boot/common/panic.c +++ b/sys/boot/common/panic.c @@ -1,10 +1,7 @@ /* - * $FreeBSD: src/sys/boot/common/panic.c,v 1.5 1999/08/28 00:39:51 peter Exp $ - * $DragonFly: src/sys/boot/common/panic.c,v 1.3 2003/11/09 02:22:33 dillon Exp $ - * From: $NetBSD: panic.c,v 1.2 1997/03/22 01:48:36 thorpej Exp $ + * $NetBSD: panic.c,v 1.2 1997/03/22 01:48:36 thorpej Exp $ */ - -/* +/*- * Copyright (c) 1996 * Matthias Drochner. All rights reserved. * @@ -34,9 +31,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * $FreeBSD: src/sys/boot/common/panic.c,v 1.7 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/panic.c,v 1.4 2003/11/10 06:08:31 dillon Exp $ */ - #include #include @@ -51,5 +49,8 @@ panic(const char *fmt,...) __va_end(ap); printf("\n"); + printf("--> Press a key on the console to reboot <--\n"); + getchar(); + printf("Rebooting...\n"); exit(1); } diff --git a/sys/boot/common/pnp.c b/sys/boot/common/pnp.c index 8c47a08935..b69b4adef3 100644 --- a/sys/boot/common/pnp.c +++ b/sys/boot/common/pnp.c @@ -1,9 +1,10 @@ /* * mjs copyright * - * $FreeBSD: src/sys/boot/common/pnp.c,v 1.9.2.2 2000/12/28 13:12:36 ps Exp $ - * $DragonFly: src/sys/boot/common/pnp.c,v 1.2 2003/06/17 04:28:17 dillon Exp $ + * $FreeBSD: src/sys/boot/common/pnp.c,v 1.16 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/pnp.c,v 1.3 2003/11/10 06:08:31 dillon Exp $ */ + /* * "Plug and Play" functionality. * @@ -16,7 +17,7 @@ #include #include -STAILQ_HEAD(,pnpinfo) pnp_devices; +struct pnpinfo_stql pnp_devices; static int pnp_devices_initted = 0; static void pnp_discard(void); @@ -67,8 +68,8 @@ pnp_scan(int argc, char *argv[]) if (verbose) { pager_open(); pager_output("PNP scan summary:\n"); - for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) { - pager_output(pi->pi_ident.stqh_first->id_ident); /* first ident should be canonical */ + STAILQ_FOREACH(pi, &pnp_devices, pi_link) { + pager_output(STAILQ_FIRST(&pi->pi_ident)->id_ident); /* first ident should be canonical */ if (pi->pi_desc != NULL) { pager_output(" : "); pager_output(pi->pi_desc); @@ -93,7 +94,7 @@ pnp_load(int argc, char *argv[]) char *modfname; /* find anything? */ - if (pnp_devices.stqh_first != NULL) { + if (STAILQ_FIRST(&pnp_devices) != NULL) { /* check for kernel, assign modules handled by static drivers there */ if (pnp_scankernel()) { @@ -112,13 +113,13 @@ pnp_load(int argc, char *argv[]) } /* try to load any modules that have been nominated */ - for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) { + STAILQ_FOREACH(pi, &pnp_devices, pi_link) { /* Already loaded? */ - if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) { + if ((pi->pi_module != NULL) && (file_findfile(pi->pi_module, NULL) == NULL)) { modfname = malloc(strlen(pi->pi_module) + 4); sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */ if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv)) - printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident.stqh_first->id_ident); + printf("Could not load module '%s' for device '%s'\n", modfname, STAILQ_FIRST(&pi->pi_ident)->id_ident); free(modfname); } } @@ -134,8 +135,8 @@ pnp_discard(void) { struct pnpinfo *pi; - while (pnp_devices.stqh_first != NULL) { - pi = pnp_devices.stqh_first; + while (STAILQ_FIRST(&pnp_devices) != NULL) { + pi = STAILQ_FIRST(&pnp_devices); STAILQ_REMOVE_HEAD(&pnp_devices, pi_link); pnp_freeinfo(pi); } @@ -258,14 +259,14 @@ pnp_readconf(char *path) * assigned. * XXX no revision parse/test here yet. */ - for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) { + STAILQ_FOREACH(pi, &pnp_devices, pi_link) { /* no driver assigned, bus matches OK */ if ((pi->pi_module == NULL) && !strcmp(pi->pi_handler->pp_name, currbus)) { /* scan idents, take first match */ - for (id = pi->pi_ident.stqh_first; id != NULL; id = id->id_link.stqe_next) + STAILQ_FOREACH(id, &pi->pi_ident, id_link) if (!strcmp(id->id_ident, ident)) break; @@ -301,7 +302,7 @@ pnp_addident(struct pnpinfo *pi, char *ident) { struct pnpident *id; - for (id = pi->pi_ident.stqh_first; id != NULL; id = id->id_link.stqe_next) + STAILQ_FOREACH(id, &pi->pi_ident, id_link) if (!strcmp(id->id_ident, ident)) return; /* already have this one */ @@ -332,8 +333,8 @@ pnp_freeinfo(struct pnpinfo *pi) { struct pnpident *id; - while (pi->pi_ident.stqh_first != NULL) { - id = pi->pi_ident.stqh_first; + while (!STAILQ_EMPTY(&pi->pi_ident)) { + id = STAILQ_FIRST(&pi->pi_ident); STAILQ_REMOVE_HEAD(&pi->pi_ident, id_link); free(id->id_ident); free(id); diff --git a/sys/boot/common/pnpdata b/sys/boot/common/pnpdata index a2a1ac2d0b..8b4012d19f 100644 --- a/sys/boot/common/pnpdata +++ b/sys/boot/common/pnpdata @@ -1,6 +1,6 @@ # -# $FreeBSD: src/sys/boot/common/pnpdata,v 1.2.2.1 2002/10/05 18:31:47 scottl Exp $ -# $DragonFly: src/sys/boot/common/pnpdata,v 1.2 2003/06/17 04:28:17 dillon Exp $ +# $FreeBSD: src/sys/boot/common/pnpdata,v 1.2 1999/08/28 00:39:51 peter Exp $ +# $DragonFly: src/sys/boot/common/pnpdata,v 1.3 2003/11/10 06:08:31 dillon Exp $ # # This file contains the system default Plug-and-Play data. It is # derived from a number of sources, including: @@ -125,6 +125,7 @@ ident=PNP8323 module=ed # SMC EtherCard (All Types except 8013/A) ident=PNP8390 module=ed # Generic network adapter # --SCSI, Proprietary CD Adapters-- +ident=PNPA003 module=matcd # Panasonic proprietary CD-ROM adapter (SBPro/SB16) ident=PNPA02B module=scd # Sony proprietary CD-ROM controller ident=PNPA030 module=mcd # Mitsumi LU-005 Single Speed CD-ROM controller + drive ident=PNPA031 module=mcd # Mitsumi FX-001 Single Speed CD-ROM controller + drive diff --git a/sys/boot/common/ufsread.c b/sys/boot/common/ufsread.c new file mode 100644 index 0000000000..f3db742f9e --- /dev/null +++ b/sys/boot/common/ufsread.c @@ -0,0 +1,271 @@ +/*- + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Marshall + * Kirk McKusick and Network Associates Laboratories, the Security + * Research Division of Network Associates, Inc. under DARPA/SPAWAR + * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS + * research program + * + * Copyright (c) 1998 Robert Nordier + * All rights reserved. + * + * Redistribution and use in source and binary forms are freely + * permitted provided that the above copyright notice and this + * paragraph and the following disclaimer are duplicated in all + * such forms. + * + * This software is provided "AS IS" and without any express or + * implied warranties, including, without limitation, the implied + * warranties of merchantability and fitness for a particular + * purpose. + * + * $FreeBSD: src/sys/boot/common/ufsread.c,v 1.12 2003/08/25 23:30:41 obrien Exp $ + * $DragonFly: src/sys/boot/common/ufsread.c,v 1.1 2003/11/10 06:08:31 dillon Exp $ + */ + +#include "dinode.h" +#include "fs.h" +#ifdef __i386__ +/* XXX: Revert to old (broken for over 1.5Tb filesystems) version of cgbase + (see sys/ufs/ffs/fs.h rev 1.39) so that i386 boot loader (boot2) can + support both UFS1 and UFS2 again. */ +#undef cgbase +#define cgbase(fs, c) ((ufs2_daddr_t)((fs)->fs_fpg * (c))) +#endif + +/* + * We use 4k `virtual' blocks for filesystem data, whatever the actual + * filesystem block size. FFS blocks are always a multiple of 4k. + */ +#define VBLKSHIFT 12 +#define VBLKSIZE (1 << VBLKSHIFT) +#define VBLKMASK (VBLKSIZE - 1) +#define DBPERVBLK (VBLKSIZE / DEV_BSIZE) +#define INDIRPERVBLK(fs) (NINDIR(fs) / ((fs)->fs_bsize >> VBLKSHIFT)) +#define IPERVBLK(fs) (INOPB(fs) / ((fs)->fs_bsize >> VBLKSHIFT)) +#define INO_TO_VBA(fs, ipervblk, x) \ + (fsbtodb(fs, cgimin(fs, ino_to_cg(fs, x))) + \ + (((x) % (fs)->fs_ipg) / (ipervblk) * DBPERVBLK)) +#define INO_TO_VBO(ipervblk, x) ((x) % ipervblk) +#define FS_TO_VBA(fs, fsb, off) (fsbtodb(fs, fsb) + \ + ((off) / VBLKSIZE) * DBPERVBLK) +#define FS_TO_VBO(fs, fsb, off) ((off) & VBLKMASK) + +/* Buffers that must not span a 64k boundary. */ +struct dmadat { + char blkbuf[VBLKSIZE]; /* filesystem blocks */ + char indbuf[VBLKSIZE]; /* indir blocks */ + char sbbuf[SBLOCKSIZE]; /* superblock */ + char secbuf[DEV_BSIZE]; /* for MBR/disklabel */ +}; +static struct dmadat *dmadat; + +static ino_t lookup(const char *); +static ssize_t fsread(ino_t, void *, size_t); + +static int ls, dsk_meta; +static uint32_t fs_off; + +static __inline__ int +fsfind(const char *name, ino_t * ino) +{ + char buf[DEV_BSIZE]; + struct dirent *d; + char *s; + ssize_t n; + + fs_off = 0; + while ((n = fsread(*ino, buf, DEV_BSIZE)) > 0) + for (s = buf; s < buf + DEV_BSIZE;) { + d = (void *)s; + if (ls) + printf("%s ", d->d_name); + else if (!strcmp(name, d->d_name)) { + *ino = d->d_fileno; + return d->d_type; + } + s += d->d_reclen; + } + if (n != -1 && ls) + printf("\n"); + return 0; +} + +static ino_t +lookup(const char *path) +{ + char name[MAXNAMLEN + 1]; + const char *s; + ino_t ino; + ssize_t n; + int dt; + + ino = ROOTINO; + dt = DT_DIR; + name[0] = '/'; + name[1] = '\0'; + for (;;) { + if (*path == '/') + path++; + if (!*path) + break; + for (s = path; *s && *s != '/'; s++); + if ((n = s - path) > MAXNAMLEN) + return 0; + ls = *path == '?' && n == 1 && !*s; + memcpy(name, path, n); + name[n] = 0; + if (dt != DT_DIR) { + printf("%s: not a directory.\n", name); + return (0); + } + if ((dt = fsfind(name, &ino)) <= 0) + break; + path = s; + } + return dt == DT_REG ? ino : 0; +} + +/* + * Possible superblock locations ordered from most to least likely. + */ +static int sblock_try[] = SBLOCKSEARCH; + +#if defined(UFS2_ONLY) +#define DIP(field) dp2.field +#elif defined(UFS1_ONLY) +#define DIP(field) dp1.field +#else +#define DIP(field) fs->fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field +#endif + +static ssize_t +fsread(ino_t inode, void *buf, size_t nbyte) +{ +#ifndef UFS2_ONLY + static struct ufs1_dinode dp1; +#endif +#ifndef UFS1_ONLY + static struct ufs2_dinode dp2; +#endif + static ino_t inomap; + char *blkbuf; + void *indbuf; + struct fs *fs; + char *s; + size_t n, nb, size, off, vboff; + ufs_lbn_t lbn; + ufs2_daddr_t addr, vbaddr; + static ufs2_daddr_t blkmap, indmap; + u_int u; + + + blkbuf = dmadat->blkbuf; + indbuf = dmadat->indbuf; + fs = (struct fs *)dmadat->sbbuf; + if (!dsk_meta) { + inomap = 0; + for (n = 0; sblock_try[n] != -1; n++) { + if (dskread(fs, sblock_try[n] / DEV_BSIZE, + SBLOCKSIZE / DEV_BSIZE)) + return -1; + if (( +#if defined(UFS1_ONLY) + fs->fs_magic == FS_UFS1_MAGIC +#elif defined(UFS2_ONLY) + (fs->fs_magic == FS_UFS2_MAGIC && + fs->fs_sblockloc == sblock_try[n]) +#else + fs->fs_magic == FS_UFS1_MAGIC || + (fs->fs_magic == FS_UFS2_MAGIC && + fs->fs_sblockloc == sblock_try[n]) +#endif + ) && + fs->fs_bsize <= MAXBSIZE && + fs->fs_bsize >= sizeof(struct fs)) + break; + } + if (sblock_try[n] == -1) { + printf("Not ufs\n"); + return -1; + } + dsk_meta++; + } + if (!inode) + return 0; + if (inomap != inode) { + n = IPERVBLK(fs); + if (dskread(blkbuf, INO_TO_VBA(fs, n, inode), DBPERVBLK)) + return -1; + n = INO_TO_VBO(n, inode); +#if defined(UFS1_ONLY) + dp1 = ((struct ufs1_dinode *)blkbuf)[n]; +#elif defined(UFS2_ONLY) + dp2 = ((struct ufs2_dinode *)blkbuf)[n]; +#else + if (fs->fs_magic == FS_UFS1_MAGIC) + dp1 = ((struct ufs1_dinode *)blkbuf)[n]; + else + dp2 = ((struct ufs2_dinode *)blkbuf)[n]; +#endif + inomap = inode; + fs_off = 0; + blkmap = indmap = 0; + } + s = buf; + size = DIP(di_size); + n = size - fs_off; + if (nbyte > n) + nbyte = n; + nb = nbyte; + while (nb) { + lbn = lblkno(fs, fs_off); + off = blkoff(fs, fs_off); + if (lbn < NDADDR) { + addr = DIP(di_db[lbn]); + } else if (lbn < NDADDR + NINDIR(fs)) { + n = INDIRPERVBLK(fs); + addr = DIP(di_ib[0]); + u = (u_int)(lbn - NDADDR) / (n * DBPERVBLK); + vbaddr = fsbtodb(fs, addr) + u; + if (indmap != vbaddr) { + if (dskread(indbuf, vbaddr, DBPERVBLK)) + return -1; + indmap = vbaddr; + } + n = (lbn - NDADDR) & (n - 1); +#if defined(UFS1_ONLY) + addr = ((ufs1_daddr_t *)indbuf)[n]; +#elif defined(UFS2_ONLY) + addr = ((ufs2_daddr_t *)indbuf)[n]; +#else + if (fs->fs_magic == FS_UFS1_MAGIC) + addr = ((ufs1_daddr_t *)indbuf)[n]; + else + addr = ((ufs2_daddr_t *)indbuf)[n]; +#endif + } else { + return -1; + } + vbaddr = fsbtodb(fs, addr) + (off >> VBLKSHIFT) * DBPERVBLK; + vboff = off & VBLKMASK; + n = sblksize(fs, size, lbn) - (off & ~VBLKMASK); + if (n > VBLKSIZE) + n = VBLKSIZE; + if (blkmap != vbaddr) { + if (dskread(blkbuf, vbaddr, n >> DEV_BSHIFT)) + return -1; + blkmap = vbaddr; + } + n -= vboff; + if (n > nb) + n = nb; + memcpy(s, blkbuf + vboff, n); + s += n; + fs_off += n; + nb -= n; + } + return nbyte; +} diff --git a/sys/boot/efi/Makefile b/sys/boot/efi/Makefile new file mode 100644 index 0000000000..2664d4ace8 --- /dev/null +++ b/sys/boot/efi/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD: src/sys/boot/efi/Makefile,v 1.1 2001/06/09 16:49:48 dfr Exp $ +# $DragonFly: src/sys/boot/efi/Makefile,v 1.1 2003/11/10 06:08:32 dillon Exp $ + +SUBDIR= libefi loader + +.include diff --git a/sys/boot/efi/Makefile.inc b/sys/boot/efi/Makefile.inc new file mode 100644 index 0000000000..c642433f60 --- /dev/null +++ b/sys/boot/efi/Makefile.inc @@ -0,0 +1,5 @@ +# $FreeBSD: src/sys/boot/efi/Makefile.inc,v 1.6 2002/12/10 04:20:15 marcel Exp $ +# $DragonFly: src/sys/boot/efi/Makefile.inc,v 1.1 2003/11/10 06:08:32 dillon Exp $ + +# Options used when building app-specific efi components +CFLAGS+= -ffreestanding -fshort-wchar -Wformat diff --git a/sys/boot/efi/include/README b/sys/boot/efi/include/README new file mode 100644 index 0000000000..4ec661bbf9 --- /dev/null +++ b/sys/boot/efi/include/README @@ -0,0 +1,36 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/README,v 1.1 2001/06/09 16:49:49 dfr Exp $ + * $DragonFly: src/sys/boot/efi/include/README,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ + +Files in this directory and subdirectories are subject to the following +copyright unless superceded or supplemented by additional specific license +terms found in the file headers of individual files. + +Copyright (c) 1998-2000 Intel Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +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. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL INTEL 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. THE EFI SPECIFICATION AND ALL +OTHER INFORMATION ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO +WARRANTIES, AND ARE SUBJECT TO CHANGE WITHOUT NOTICE. diff --git a/sys/boot/efi/include/efi.h b/sys/boot/efi/include/efi.h new file mode 100644 index 0000000000..1e4b2980a4 --- /dev/null +++ b/sys/boot/efi/include/efi.h @@ -0,0 +1,52 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efi.h,v 1.3 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efi.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efi.h + +Abstract: + + Public EFI header files + + + +Revision History + +--*/ + +/* + * Build flags on input + * EFI32 + * EFI_DEBUG - Enable debugging code + * EFI_NT_EMULATOR - Building for running under NT + */ + +#ifndef _EFI_INCLUDE_ +#define _EFI_INCLUDE_ + +#define EFI_FIRMWARE_VENDOR L"INTEL" +#define EFI_FIRMWARE_MAJOR_REVISION 12 +#define EFI_FIRMWARE_MINOR_REVISION 33 +#define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION)) + +#include "efibind.h" +#include "efidef.h" +#include "efidevp.h" +#include "efiprot.h" +#include "eficon.h" +#include "efiser.h" +#include "efi_nii.h" +#include "efipxebc.h" +#include "efinet.h" +#include "efiapi.h" +#include "efifs.h" +#include "efifpswa.h" +#include "efierr.h" + +#endif diff --git a/sys/boot/efi/include/efi_nii.h b/sys/boot/efi/include/efi_nii.h new file mode 100644 index 0000000000..adb43eb56e --- /dev/null +++ b/sys/boot/efi/include/efi_nii.h @@ -0,0 +1,85 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efi_nii.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efi_nii.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_NII_H +#define _EFI_NII_H + +/*++ +Copyright (c) 2000 Intel Corporation + +Module name: + efi_nii.h + +Abstract: + +Revision history: + 2000-Feb-18 M(f)J GUID updated. + Structure order changed for machine word alignment. + Added StringId[4] to structure. + + 2000-Feb-14 M(f)J Genesis. +--*/ + +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL \ + { 0xE18541CD, 0xF755, 0x4f73, 0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29 } + +#define EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE_REVISION 0x00010000 + +typedef enum { + EfiNetworkInterfaceUndi = 1 +} EFI_NETWORK_INTERFACE_TYPE; + +typedef struct { + + /* Revision of the network interface identifier protocol interface. */ + UINT64 Revision; + + /* + * Address of the first byte of the identifying structure for this + * network interface. This is set to zero if there is no structure. + * For PXE/UNDI this is the first byte of the !PXE structure. + */ + UINT64 ID; + + /* + * Address of the UNrelocated driver/ROM image. This is set + * to zero if there is no driver/ROM image. + * For 16-bit UNDI, this is the first byte of the option ROM in + * upper memory. + * For 32/64-bit S/W UNDI, this is the first byte of the EFI ROM + * image. + * For H/W UNDI, this is set to zero. + */ + UINT64 ImageAddr; + + /* + * Size of the UNrelocated driver/ROM image of this network interface. + * This is set to zero if there is no driver/ROM image. + */ + UINT32 ImageSize; + + /* + * 4 char ASCII string to go in class identifier (option 60) in DHCP + * and Boot Server discover packets. + * For EfiNetworkInterfaceUndi this field is "UNDI". + * For EfiNetworkInterfaceSnp this field is "SNPN". + */ + CHAR8 StringId[4]; + + /* + * Information to be placed into the PXE DHCP and Discover packets. + * This is the network interface type and version number that will + * be placed into DHCP option 94 (client network interface identifier). + */ + UINT8 Type; + UINT8 MajorVer; + UINT8 MinorVer; + + BOOLEAN Ipv6Supported; + UINT8 IfNum; /* interface number to be used with pxeid structure */ +} EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE; + +extern EFI_GUID NetworkInterfaceIdentifierProtocol; + +#endif /* _EFI_NII_H */ diff --git a/sys/boot/efi/include/efiapi.h b/sys/boot/efi/include/efiapi.h new file mode 100644 index 0000000000..512049828b --- /dev/null +++ b/sys/boot/efi/include/efiapi.h @@ -0,0 +1,707 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efiapi.h,v 1.5 2002/12/08 20:47:44 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efiapi.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_API_H +#define _EFI_API_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiapi.h + +Abstract: + + Global EFI runtime & boot service interfaces + + + + +Revision History + +--*/ + +/* + * EFI Specification Revision + */ + +#define EFI_SPECIFICATION_MAJOR_REVISION 1 +#define EFI_SPECIFICATION_MINOR_REVISION 02 + +/* + * Declare forward referenced data structures + */ + +INTERFACE_DECL(_EFI_SYSTEM_TABLE); + +/* + * EFI Memory + */ + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_PAGES) ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NoPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_PAGES) ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MEMORY_MAP) ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +#define NextMemoryDescriptor(Ptr,Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size)) + + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_POOL) ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_POOL) ( + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + + +#define EFI_OPTIONAL_PTR 0x00000001 +#define EFI_INTERNAL_FNC 0x00000002 /* Pointer to internal runtime fnc */ +#define EFI_INTERNAL_PTR 0x00000004 /* Pointer to internal runtime data */ + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONVERT_POINTER) ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + + +/* + * EFI Events + */ + + + +#define EVT_TIMER 0x80000000 +#define EVT_RUNTIME 0x40000000 +#define EVT_RUNTIME_CONTEXT 0x20000000 + +#define EVT_NOTIFY_WAIT 0x00000100 +#define EVT_NOTIFY_SIGNAL 0x00000200 + +#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define EVT_EFI_SIGNAL_MASK 0x000000FF +#define EVT_EFI_SIGNAL_MAX 2 + +typedef +VOID +(EFIAPI *EFI_EVENT_NOTIFY) ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CREATE_EVENT) ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *Event + ); + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative, + TimerTypeMax +} EFI_TIMER_DELAY; + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIMER) ( + IN EFI_EVENT Event, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIGNAL_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_WAIT_FOR_EVENT) ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *Event, + OUT UINTN *Index + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CHECK_EVENT) ( + IN EFI_EVENT Event + ); + +/* + * Task priority level + */ + +#define TPL_APPLICATION 4 +#define TPL_CALLBACK 8 +#define TPL_NOTIFY 16 +#define TPL_HIGH_LEVEL 31 + +typedef +EFI_TPL +(EFIAPI *EFI_RAISE_TPL) ( + IN EFI_TPL NewTpl + ); + +typedef +VOID +(EFIAPI *EFI_RESTORE_TPL) ( + IN EFI_TPL OldTpl + ); + + +/* + * EFI platform varibles + */ + +#define EFI_GLOBAL_VARIABLE \ + { 0x8BE4DF61, 0x93CA, 0x11d2, 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } + +/* Variable attributes */ +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 + +/* Variable size limitation */ +#define EFI_MAXIMUM_VARIABLE_SIZE 1024 + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +/* + * EFI Time + */ + +typedef struct { + UINT32 Resolution; /* 1e-6 parts per million */ + UINT32 Accuracy; /* hertz */ + BOOLEAN SetsToZero; /* Set clears sub-second time */ +} EFI_TIME_CAPABILITIES; + + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_TIME) ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIME) ( + IN EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_WAKEUP_TIME) ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WAKEUP_TIME) ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + + +/* + * Image functions + */ + + +/* PE32+ Subsystem type for EFI images */ + +#if !defined(IMAGE_SUBSYSTEM_EFI_APPLICATION) +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#endif + +/* PE32+ Machine type for EFI images */ + +#if !defined(EFI_IMAGE_MACHINE_IA32) +#define EFI_IMAGE_MACHINE_IA32 0x014c +#endif + +#if !defined(EFI_IMAGE_MACHINE_IA64) +#define EFI_IMAGE_MACHINE_IA64 0x0200 +#endif + +/* Image Entry prototype */ + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_ENTRY_POINT) ( + IN EFI_HANDLE ImageHandle, + IN struct _EFI_SYSTEM_TABLE *SystemTable + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_LOAD) ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_START) ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT) ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS ExitStatus, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_UNLOAD) ( + IN EFI_HANDLE ImageHandle + ); + + +/* Image handle */ +#define LOADED_IMAGE_PROTOCOL \ + { 0x5B1B31A1, 0x9562, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } + +#define EFI_IMAGE_INFORMATION_REVISION 0x1000 +typedef struct { + UINT32 Revision; + EFI_HANDLE ParentHandle; + struct _EFI_SYSTEM_TABLE *SystemTable; + + /* Source location of image */ + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH *FilePath; + VOID *Reserved; + + /* Images load options */ + UINT32 LoadOptionsSize; + VOID *LoadOptions; + + /* Location of where image was loaded */ + VOID *ImageBase; + UINT64 ImageSize; + EFI_MEMORY_TYPE ImageCodeType; + EFI_MEMORY_TYPE ImageDataType; + + /* If the driver image supports a dynamic unload request */ + EFI_IMAGE_UNLOAD Unload; + +} EFI_LOADED_IMAGE; + + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT_BOOT_SERVICES) ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +/* + * Misc + */ + + +typedef +EFI_STATUS +(EFIAPI *EFI_STALL) ( + IN UINTN Microseconds + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WATCHDOG_TIMER) ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + + +typedef enum { + EfiResetCold, + EfiResetWarm +} EFI_RESET_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_RESET_SYSTEM) ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN CHAR16 *ResetData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) ( + OUT UINT64 *Count + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) ( + OUT UINT32 *HighCount + ); + +/* + * Protocol handler functions + */ + +typedef enum { + EFI_NATIVE_INTERFACE, + EFI_PCODE_INTERFACE +} EFI_INTERFACE_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) ( + IN OUT EFI_HANDLE *Handle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HANDLE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +typedef enum { + AllHandles, + ByRegisterNotify, + ByProtocol +} EFI_LOCATE_SEARCH_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_DEVICE_PATH) ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH **DevicePath, + OUT EFI_HANDLE *Device + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_RESERVED_SERVICE) ( + VOID + ); + +/* + * Standard EFI table header + */ + +typedef struct _EFI_TABLE_HEARDER { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + + +/* + * EFI Runtime Serivces Table + */ + +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_RUNTIME_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) + +typedef struct { + EFI_TABLE_HEADER Hdr; + + /* Time services */ + + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + EFI_GET_WAKEUP_TIME GetWakeupTime; + EFI_SET_WAKEUP_TIME SetWakeupTime; + + /* Virtual memory services */ + + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; + EFI_CONVERT_POINTER ConvertPointer; + + /* Variable serviers */ + + EFI_GET_VARIABLE GetVariable; + EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; + EFI_SET_VARIABLE SetVariable; + + /* Misc */ + + EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; + EFI_RESET_SYSTEM ResetSystem; + +} EFI_RUNTIME_SERVICES; + + +/* + * EFI Boot Services Table + */ + +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_BOOT_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) + +typedef struct _EFI_BOOT_SERVICES { + + EFI_TABLE_HEADER Hdr; + + /* Task priority functions */ + + EFI_RAISE_TPL RaiseTPL; + EFI_RESTORE_TPL RestoreTPL; + + /* Memory functions */ + + EFI_ALLOCATE_PAGES AllocatePages; + EFI_FREE_PAGES FreePages; + EFI_GET_MEMORY_MAP GetMemoryMap; + EFI_ALLOCATE_POOL AllocatePool; + EFI_FREE_POOL FreePool; + + /* Event & timer functions */ + + EFI_CREATE_EVENT CreateEvent; + EFI_SET_TIMER SetTimer; + EFI_WAIT_FOR_EVENT WaitForEvent; + EFI_SIGNAL_EVENT SignalEvent; + EFI_CLOSE_EVENT CloseEvent; + EFI_CHECK_EVENT CheckEvent; + + /* Protocol handler functions */ + + EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; + EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; + EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; + EFI_HANDLE_PROTOCOL HandleProtocol; + EFI_HANDLE_PROTOCOL PCHandleProtocol; + EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; + EFI_LOCATE_HANDLE LocateHandle; + EFI_LOCATE_DEVICE_PATH LocateDevicePath; + EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; + + /* Image functions */ + + EFI_IMAGE_LOAD LoadImage; + EFI_IMAGE_START StartImage; + EFI_EXIT Exit; + EFI_IMAGE_UNLOAD UnloadImage; + EFI_EXIT_BOOT_SERVICES ExitBootServices; + + /* Misc functions */ + + EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; + EFI_STALL Stall; + EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; + +} EFI_BOOT_SERVICES; + + +/* + * EFI Configuration Table and GUID definitions + */ + +#define MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define SAL_SYSTEM_TABLE_GUID \ + { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +/* DIG64 Headless Console & Debug Port Table. */ +#define HCDP_TABLE_GUID \ + {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}} + +typedef struct _EFI_CONFIGURATION_TABLE { + EFI_GUID VendorGuid; + VOID *VendorTable; +} EFI_CONFIGURATION_TABLE; + + +/* + * EFI System Table + */ + + + + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_SYSTEM_TABLE_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) + +typedef struct _EFI_SYSTEM_TABLE { + EFI_TABLE_HEADER Hdr; + + CHAR16 *FirmwareVendor; + UINT32 FirmwareRevision; + + EFI_HANDLE ConsoleInHandle; + SIMPLE_INPUT_INTERFACE *ConIn; + + EFI_HANDLE ConsoleOutHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut; + + EFI_HANDLE StandardErrorHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr; + + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + + UINTN NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; + +} EFI_SYSTEM_TABLE; + +#endif diff --git a/sys/boot/efi/include/eficon.h b/sys/boot/efi/include/eficon.h new file mode 100644 index 0000000000..f714d68894 --- /dev/null +++ b/sys/boot/efi/include/eficon.h @@ -0,0 +1,302 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/eficon.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/eficon.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_CON_H +#define _EFI_CON_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + eficon.h + +Abstract: + + EFI console protocols + + + +Revision History + +--*/ + +/* + * Text output protocol + */ + +#define SIMPLE_TEXT_OUTPUT_PROTOCOL \ + { 0x387477c2, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_SIMPLE_TEXT_OUTPUT_INTERFACE); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_RESET) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_OUTPUT_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_TEST_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_QUERY_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber, + OUT UINTN *Columns, + OUT UINTN *Rows + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Attribute + ); + +#define EFI_BLACK 0x00 +#define EFI_BLUE 0x01 +#define EFI_GREEN 0x02 +#define EFI_CYAN (EFI_BLUE | EFI_GREEN) +#define EFI_RED 0x04 +#define EFI_MAGENTA (EFI_BLUE | EFI_RED) +#define EFI_BROWN (EFI_GREEN | EFI_RED) +#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED) +#define EFI_BRIGHT 0x08 +#define EFI_DARKGRAY (EFI_BRIGHT) +#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT) +#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT) +#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT) +#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT) +#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT) +#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT) +#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT) + +#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4)) + +#define EFI_BACKGROUND_BLACK 0x00 +#define EFI_BACKGROUND_BLUE 0x10 +#define EFI_BACKGROUND_GREEN 0x20 +#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN) +#define EFI_BACKGROUND_RED 0x40 +#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) + + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_CLEAR_SCREEN) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Column, + IN UINTN Row + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_ENABLE_CURSOR) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN Enable + ); + +typedef struct { + INT32 MaxMode; + /* current settings */ + INT32 Mode; + INT32 Attribute; + INT32 CursorColumn; + INT32 CursorRow; + BOOLEAN CursorVisible; +} SIMPLE_TEXT_OUTPUT_MODE; + +typedef struct _SIMPLE_TEXT_OUTPUT_INTERFACE { + EFI_TEXT_RESET Reset; + + EFI_TEXT_OUTPUT_STRING OutputString; + EFI_TEXT_TEST_STRING TestString; + + EFI_TEXT_QUERY_MODE QueryMode; + EFI_TEXT_SET_MODE SetMode; + EFI_TEXT_SET_ATTRIBUTE SetAttribute; + + EFI_TEXT_CLEAR_SCREEN ClearScreen; + EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; + EFI_TEXT_ENABLE_CURSOR EnableCursor; + + /* Current mode */ + SIMPLE_TEXT_OUTPUT_MODE *Mode; +} SIMPLE_TEXT_OUTPUT_INTERFACE; + +/* + * Define's for required EFI Unicode Box Draw character + */ + +#define BOXDRAW_HORIZONTAL 0x2500 +#define BOXDRAW_VERTICAL 0x2502 +#define BOXDRAW_DOWN_RIGHT 0x250c +#define BOXDRAW_DOWN_LEFT 0x2510 +#define BOXDRAW_UP_RIGHT 0x2514 +#define BOXDRAW_UP_LEFT 0x2518 +#define BOXDRAW_VERTICAL_RIGHT 0x251c +#define BOXDRAW_VERTICAL_LEFT 0x2524 +#define BOXDRAW_DOWN_HORIZONTAL 0x252c +#define BOXDRAW_UP_HORIZONTAL 0x2534 +#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c + +#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550 +#define BOXDRAW_DOUBLE_VERTICAL 0x2551 +#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552 +#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553 +#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554 + +#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555 +#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556 +#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557 + +#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558 +#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559 +#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a + +#define BOXDRAW_UP_LEFT_DOUBLE 0x255b +#define BOXDRAW_UP_DOUBLE_LEFT 0x255c +#define BOXDRAW_DOUBLE_UP_LEFT 0x255d + +#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e +#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f +#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560 + +#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561 +#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562 +#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563 + +#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564 +#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565 +#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566 + +#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567 +#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568 +#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569 + +#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a +#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b +#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c + +/* + * EFI Required Block Elements Code Chart + */ +#define BLOCKELEMENT_FULL_BLOCK 0x2588 +#define BLOCKELEMENT_LIGHT_SHADE 0x2591 + +/* + * EFI Required Geometric Shapes Code Chart + */ +#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2 +#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba +#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc +#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4 + +/* + * EFI Required Arrow shapes + */ +#define ARROW_UP 0x2191 +#define ARROW_DOWN 0x2193 + +/* + * Text input protocol + */ + +#define SIMPLE_TEXT_INPUT_PROTOCOL \ + { 0x387477c1, 0x69c7, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_SIMPLE_INPUT_INTERFACE); + +typedef struct { + UINT16 ScanCode; + CHAR16 UnicodeChar; +} EFI_INPUT_KEY; + +/* + * Baseline unicode control chars + */ + +#define CHAR_NULL 0x0000 +#define CHAR_BACKSPACE 0x0008 +#define CHAR_TAB 0x0009 +#define CHAR_LINEFEED 0x000A +#define CHAR_CARRIAGE_RETURN 0x000D + +/* + * Scan codes for base line keys + */ +#define SCAN_NULL 0x0000 +#define SCAN_UP 0x0001 +#define SCAN_DOWN 0x0002 +#define SCAN_RIGHT 0x0003 +#define SCAN_LEFT 0x0004 +#define SCAN_HOME 0x0005 +#define SCAN_END 0x0006 +#define SCAN_INSERT 0x0007 +#define SCAN_DELETE 0x0008 +#define SCAN_PAGE_UP 0x0009 +#define SCAN_PAGE_DOWN 0x000A +#define SCAN_F1 0x000B +#define SCAN_F2 0x000C +#define SCAN_F3 0x000D +#define SCAN_F4 0x000E +#define SCAN_F5 0x000F +#define SCAN_F6 0x0010 +#define SCAN_F7 0x0011 +#define SCAN_F8 0x0012 +#define SCAN_F9 0x0013 +#define SCAN_F10 0x0014 +#define SCAN_ESC 0x0017 + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + OUT EFI_INPUT_KEY *Key + ); + +typedef struct _SIMPLE_INPUT_INTERFACE { + EFI_INPUT_RESET Reset; + EFI_INPUT_READ_KEY ReadKeyStroke; + EFI_EVENT WaitForKey; +} SIMPLE_INPUT_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efidebug.h b/sys/boot/efi/include/efidebug.h new file mode 100644 index 0000000000..7f46bfcfbb --- /dev/null +++ b/sys/boot/efi/include/efidebug.h @@ -0,0 +1,108 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efidebug.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efidebug.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_DEBUG_H +#define _EFI_DEBUG_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efidebug.h + +Abstract: + + EFI library debug functions + + + +Revision History + +--*/ + +extern UINTN EFIDebug; + +#if EFI_DEBUG + + #define DBGASSERT(a) DbgAssert(__FILE__, __LINE__, #a) + #define DEBUG(a) DbgPrint a + +#else + + #define DBGASSERT(a) + #define DEBUG(a) + +#endif + +#if EFI_DEBUG_CLEAR_MEMORY + + #define DBGSETMEM(a,l) SetMem(a,l,(CHAR8)BAD_POINTER) + +#else + + #define DBGSETMEM(a,l) + +#endif + +#define D_INIT 0x00000001 /* Initialization style messages */ +#define D_WARN 0x00000002 /* Warnings */ +#define D_LOAD 0x00000004 /* Load events */ +#define D_FS 0x00000008 /* EFI File system */ +#define D_POOL 0x00000010 /* Alloc & Free's */ +#define D_PAGE 0x00000020 /* Alloc & Free's */ +#define D_INFO 0x00000040 /* Verbose */ +#define D_VAR 0x00000100 /* Variable */ +#define D_PARSE 0x00000200 /* Command parsing */ +#define D_BM 0x00000400 /* Boot manager */ +#define D_BLKIO 0x00001000 /* BlkIo Driver */ +#define D_BLKIO_ULTRA 0x00002000 /* BlkIo Driver */ +#define D_NET 0x00004000 /* SNI Driver */ +#define D_NET_ULTRA 0x00008000 /* SNI Driver */ +#define D_TXTIN 0x00010000 /* Simple Input Driver */ +#define D_TXTOUT 0x00020000 /* Simple Text Output Driver */ +#define D_ERROR_ATA 0x00040000 /* ATA error messages */ +#define D_ERROR 0x80000000 /* Error */ + +#define D_RESERVED 0x7fffC880 /* Bits not reserved above */ + +/* + * Current Debug level of the system, value of EFIDebug + */ +#define EFI_DBUG_MASK (D_ERROR) + +#if EFI_DEBUG + + #define ASSERT(a) if(!(a)) DBGASSERT(a) + #define ASSERT_LOCKED(l) if(!(l)->Lock) DBGASSERT(l not locked) + #define ASSERT_STRUCT(p,t) DBGASSERT(t not structure), p + +#else + + #define ASSERT(a) + #define ASSERT_LOCKED(l) + #define ASSERT_STRUCT(p,t) + +#endif + +/* + * Prototypes + */ + +INTN +DbgAssert ( + CHAR8 *file, + INTN lineno, + CHAR8 *string + ); + +INTN +DbgPrint ( + INTN mask, + CHAR8 *format, + ... + ); + +#endif diff --git a/sys/boot/efi/include/efidef.h b/sys/boot/efi/include/efidef.h new file mode 100644 index 0000000000..3c75bc9f2b --- /dev/null +++ b/sys/boot/efi/include/efidef.h @@ -0,0 +1,196 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efidef.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efidef.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_DEF_H +#define _EFI_DEF_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efidef.h + +Abstract: + + EFI definitions + + + + +Revision History + +--*/ + +typedef UINT16 CHAR16; +typedef UINT8 CHAR8; +typedef UINT8 BOOLEAN; + +#ifndef TRUE + #define TRUE ((BOOLEAN) 1) + #define FALSE ((BOOLEAN) 0) +#endif + +#ifndef NULL + #define NULL ((VOID *) 0) +#endif + +typedef UINTN EFI_STATUS; +typedef UINT64 EFI_LBA; +typedef UINTN EFI_TPL; +typedef VOID *EFI_HANDLE; +typedef VOID *EFI_EVENT; + + +/* + * Prototype argument decoration for EFI parameters to indicate + * their direction + * + * IN - argument is passed into the function + * OUT - argument (pointer) is returned from the function + * OPTIONAL - argument is optional + */ + +#ifndef IN + #define IN + #define OUT + #define OPTIONAL +#endif + + +/* + * A GUID + */ + +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} EFI_GUID; + + +/* + * Time + */ + +typedef struct { + UINT16 Year; /* 1998 - 20XX */ + UINT8 Month; /* 1 - 12 */ + UINT8 Day; /* 1 - 31 */ + UINT8 Hour; /* 0 - 23 */ + UINT8 Minute; /* 0 - 59 */ + UINT8 Second; /* 0 - 59 */ + UINT8 Pad1; + UINT32 Nanosecond; /* 0 - 999,999,999 */ + INT16 TimeZone; /* -1440 to 1440 or 2047 */ + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + +/* Bit definitions for EFI_TIME.Daylight */ +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +/* Value definition for EFI_TIME.TimeZone */ +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + + + +/* + * Networking + */ + +typedef struct { + UINT8 Addr[4]; +} EFI_IPv4_ADDRESS; + +typedef struct { + UINT8 Addr[16]; +} EFI_IPv6_ADDRESS; + +typedef struct { + UINT8 Addr[32]; +} EFI_MAC_ADDRESS; + +/* + * Memory + */ + +typedef UINT64 EFI_PHYSICAL_ADDRESS; +typedef UINT64 EFI_VIRTUAL_ADDRESS; + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +/* + * Preseve the attr on any range supplied. + * ConventialMemory must have WB,SR,SW when supplied. + * When allocating from ConventialMemory always make it WB,SR,SW + * When returning to ConventialMemory always make it WB,SR,SW + * When getting the memory map, or on RT for runtime types + */ + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +/* possible caching types for the memory range */ +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 + +/* physical memory protection on range */ +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 + +/* range requires a runtime mapping */ +#define EFI_MEMORY_RUNTIME 0x8000000000000000 + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 +typedef struct { + UINT32 Type; /* 32 bit padding */ + EFI_PHYSICAL_ADDRESS PhysicalStart; + EFI_VIRTUAL_ADDRESS VirtualStart; + UINT64 NumberOfPages; + UINT64 Attribute; +} EFI_MEMORY_DESCRIPTOR; + +/* + * International Language + */ + +typedef UINT8 ISO_639_2; +#define ISO_639_2_ENTRY_SIZE 3 + +#define EFI_PAGE_SIZE 4096 +#define EFI_PAGE_MASK 0xFFF +#define EFI_PAGE_SHIFT 12 + +#define EFI_SIZE_TO_PAGES(a) \ + ( ((a) >> EFI_PAGE_SHIFT) + ((a) & EFI_PAGE_MASK ? 1 : 0) ) + +#endif diff --git a/sys/boot/efi/include/efidevp.h b/sys/boot/efi/include/efidevp.h new file mode 100644 index 0000000000..464a51d0f5 --- /dev/null +++ b/sys/boot/efi/include/efidevp.h @@ -0,0 +1,394 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efidevp.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efidevp.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _DEVPATH_H +#define _DEVPATH_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +/* + * Device Path structures - Section C + */ + +typedef struct _EFI_DEVICE_PATH { + UINT8 Type; + UINT8 SubType; + UINT8 Length[2]; +} EFI_DEVICE_PATH; + +#define EFI_DP_TYPE_MASK 0x7F +#define EFI_DP_TYPE_UNPACKED 0x80 + +#define END_DEVICE_PATH_TYPE 0x7f + +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 +#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH)) + + +#define DP_IS_END_TYPE(a) +#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) + +#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) +#define DevicePathSubType(a) ( (a)->SubType ) +#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) ) +#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a))) +#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE ) +#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) +#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) ) +#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED ) + + +#define SetDevicePathNodeLength(a,l) { \ + (a)->Length[0] = (UINT8) (l); \ + (a)->Length[1] = (UINT8) ((l) >> 8); \ + } + +#define SetDevicePathEndNode(a) { \ + (a)->Type = END_DEVICE_PATH_TYPE; \ + (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ + (a)->Length[0] = sizeof(EFI_DEVICE_PATH); \ + (a)->Length[1] = 0; \ + } + + + +/* + * + */ +#define HARDWARE_DEVICE_PATH 0x01 + +#define HW_PCI_DP 0x01 +typedef struct _PCI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 Function; + UINT8 Device; +} PCI_DEVICE_PATH; + +#define HW_PCCARD_DP 0x02 +typedef struct _PCCARD_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 SocketNumber; +} PCCARD_DEVICE_PATH; + +#define HW_MEMMAP_DP 0x03 +typedef struct _MEMMAP_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 MemoryType; + EFI_PHYSICAL_ADDRESS StartingAddress; + EFI_PHYSICAL_ADDRESS EndingAddress; +} MEMMAP_DEVICE_PATH; + +#define HW_VENDOR_DP 0x04 +typedef struct _VENDOR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Guid; +} VENDOR_DEVICE_PATH; + +#define UNKNOWN_DEVICE_GUID \ + { 0xcf31fac5, 0xc24e, 0x11d2, 0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } + +typedef struct _UKNOWN_DEVICE_VENDOR_DP { + VENDOR_DEVICE_PATH DevicePath; + UINT8 LegacyDriveLetter; +} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH; + +#define HW_CONTROLLER_DP 0x05 +typedef struct _CONTROLLER_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Controller; +} CONTROLLER_DEVICE_PATH; + +/* + * + */ +#define ACPI_DEVICE_PATH 0x02 + +#define ACPI_DP 0x01 +typedef struct _ACPI_HID_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 HID; + UINT32 UID; +} ACPI_HID_DEVICE_PATH; + +/* + * EISA ID Macro + * EISA ID Definition 32-bits + * bits[15:0] - three character compressed ASCII EISA ID. + * bits[31:16] - binary number + * Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' + */ +#define PNP_EISA_ID_CONST 0x41d0 +#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) +#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) + +#define PNP_EISA_ID_MASK 0xffff +#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) +/* + * + */ +#define MESSAGING_DEVICE_PATH 0x03 + +#define MSG_ATAPI_DP 0x01 +typedef struct _ATAPI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 PrimarySecondary; + UINT8 SlaveMaster; + UINT16 Lun; +} ATAPI_DEVICE_PATH; + +#define MSG_SCSI_DP 0x02 +typedef struct _SCSI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 Pun; + UINT16 Lun; +} SCSI_DEVICE_PATH; + +#define MSG_FIBRECHANNEL_DP 0x03 +typedef struct _FIBRECHANNEL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 WWN; + UINT64 Lun; +} FIBRECHANNEL_DEVICE_PATH; + +#define MSG_1394_DP 0x04 +typedef struct _F1394_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 Guid; +} F1394_DEVICE_PATH; + +#define MSG_USB_DP 0x05 +typedef struct _USB_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 Port; + UINT8 Endpoint; +} USB_DEVICE_PATH; + +#define MSG_USB_CLASS_DP 0x0F +typedef struct _USB_CLASS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 VendorId; + UINT16 ProductId; + UINT8 DeviceClass; + UINT8 DeviceSubclass; + UINT8 DeviceProtocol; +} USB_CLASS_DEVICE_PATH; + +#define MSG_I2O_DP 0x06 +typedef struct _I2O_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Tid; +} I2O_DEVICE_PATH; + +#define MSG_MAC_ADDR_DP 0x0b +typedef struct _MAC_ADDR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_MAC_ADDRESS MacAddress; + UINT8 IfType; +} MAC_ADDR_DEVICE_PATH; + +#define MSG_IPv4_DP 0x0c +typedef struct _IPv4_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv4_ADDRESS LocalIpAddress; + EFI_IPv4_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; +} IPv4_DEVICE_PATH; + +#define MSG_IPv6_DP 0x0d +typedef struct _IPv6_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv6_ADDRESS LocalIpAddress; + EFI_IPv6_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; +} IPv6_DEVICE_PATH; + +#define MSG_INFINIBAND_DP 0x09 +typedef struct _INFINIBAND_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 NodeGuid; + UINT64 IocGuid; + UINT64 DeviceId; +} INFINIBAND_DEVICE_PATH; + +#define MSG_UART_DP 0x0e +typedef struct _UART_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 BaudRate; + UINT8 DataBits; + UINT8 Parity; + UINT8 StopBits; +} UART_DEVICE_PATH; + +#define MSG_VENDOR_DP 0x0A +/* Use VENDOR_DEVICE_PATH struct */ + +#define DEVICE_PATH_MESSAGING_PC_ANSI \ + { 0xe0c14753, 0xf9be, 0x11d2, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +#define DEVICE_PATH_MESSAGING_VT_100 \ + { 0xdfa66065, 0xb419, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + + + +#define MEDIA_DEVICE_PATH 0x04 + +#define MEDIA_HARDDRIVE_DP 0x01 +typedef struct _HARDDRIVE_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 PartitionNumber; + UINT64 PartitionStart; + UINT64 PartitionSize; + UINT8 Signature[16]; + UINT8 MBRType; + UINT8 SignatureType; +} HARDDRIVE_DEVICE_PATH; + +#define MBR_TYPE_PCAT 0x01 +#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 + +#define SIGNATURE_TYPE_MBR 0x01 +#define SIGNATURE_TYPE_GUID 0x02 + +#define MEDIA_CDROM_DP 0x02 +typedef struct _CDROM_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 BootEntry; + UINT64 PartitionStart; + UINT64 PartitionSize; +} CDROM_DEVICE_PATH; + +#define MEDIA_VENDOR_DP 0x03 +/* Use VENDOR_DEVICE_PATH struct */ + +#define MEDIA_FILEPATH_DP 0x04 +typedef struct _FILEPATH_DEVICE_PATH { + EFI_DEVICE_PATH Header; + CHAR16 PathName[1]; +} FILEPATH_DEVICE_PATH; + +#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName) + +#define MEDIA_PROTOCOL_DP 0x05 +typedef struct _MEDIA_PROTOCOL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Protocol; +} MEDIA_PROTOCOL_DEVICE_PATH; + + +#define BBS_DEVICE_PATH 0x05 +#define BBS_BBS_DP 0x01 +typedef struct _BBS_BBS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 DeviceType; + UINT16 StatusFlag; + CHAR8 String[1]; +} BBS_BBS_DEVICE_PATH; + +/* DeviceType definitions - from BBS specification */ +#define BBS_TYPE_FLOPPY 0x01 +#define BBS_TYPE_HARDDRIVE 0x02 +#define BBS_TYPE_CDROM 0x03 +#define BBS_TYPE_PCMCIA 0x04 +#define BBS_TYPE_USB 0x05 +#define BBS_TYPE_EMBEDDED_NETWORK 0x06 +#define BBS_TYPE_DEV 0x80 +#define BBS_TYPE_UNKNOWN 0xFF + +typedef union { + EFI_DEVICE_PATH DevPath; + PCI_DEVICE_PATH Pci; + PCCARD_DEVICE_PATH PcCard; + MEMMAP_DEVICE_PATH MemMap; + VENDOR_DEVICE_PATH Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor; + CONTROLLER_DEVICE_PATH Controller; + ACPI_HID_DEVICE_PATH Acpi; + + ATAPI_DEVICE_PATH Atapi; + SCSI_DEVICE_PATH Scsi; + FIBRECHANNEL_DEVICE_PATH FibreChannel; + + F1394_DEVICE_PATH F1394; + USB_DEVICE_PATH Usb; + USB_CLASS_DEVICE_PATH UsbClass; + I2O_DEVICE_PATH I2O; + MAC_ADDR_DEVICE_PATH MacAddr; + IPv4_DEVICE_PATH Ipv4; + IPv6_DEVICE_PATH Ipv6; + INFINIBAND_DEVICE_PATH InfiniBand; + UART_DEVICE_PATH Uart; + + HARDDRIVE_DEVICE_PATH HardDrive; + CDROM_DEVICE_PATH CD; + + FILEPATH_DEVICE_PATH FilePath; + MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; + + BBS_BBS_DEVICE_PATH Bbs; + +} EFI_DEV_PATH; + +typedef union { + EFI_DEVICE_PATH *DevPath; + PCI_DEVICE_PATH *Pci; + PCCARD_DEVICE_PATH *PcCard; + MEMMAP_DEVICE_PATH *MemMap; + VENDOR_DEVICE_PATH *Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor; + CONTROLLER_DEVICE_PATH *Controller; + ACPI_HID_DEVICE_PATH *Acpi; + + ATAPI_DEVICE_PATH *Atapi; + SCSI_DEVICE_PATH *Scsi; + FIBRECHANNEL_DEVICE_PATH *FibreChannel; + + F1394_DEVICE_PATH *F1394; + USB_DEVICE_PATH *Usb; + USB_CLASS_DEVICE_PATH *UsbClass; + I2O_DEVICE_PATH *I2O; + MAC_ADDR_DEVICE_PATH *MacAddr; + IPv4_DEVICE_PATH *Ipv4; + IPv6_DEVICE_PATH *Ipv6; + INFINIBAND_DEVICE_PATH *InfiniBand; + UART_DEVICE_PATH *Uart; + + HARDDRIVE_DEVICE_PATH *HardDrive; + + FILEPATH_DEVICE_PATH *FilePath; + MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; + + CDROM_DEVICE_PATH *CD; + BBS_BBS_DEVICE_PATH *Bbs; + +} EFI_DEV_PATH_PTR; + + +#endif diff --git a/sys/boot/efi/include/efierr.h b/sys/boot/efi/include/efierr.h new file mode 100644 index 0000000000..19fae494c3 --- /dev/null +++ b/sys/boot/efi/include/efierr.h @@ -0,0 +1,63 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efierr.h,v 1.1 2001/06/09 16:49:49 dfr Exp $ + * $DragonFly: src/sys/boot/efi/include/efierr.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_ERR_H +#define _EFI_ERR_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efierr.h + +Abstract: + + EFI error codes + + + + +Revision History + +--*/ + + +#define EFIWARN(a) (a) +#define EFI_ERROR(a) (((INTN) a) < 0) + + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFIERR(1) +#define EFI_INVALID_PARAMETER EFIERR(2) +#define EFI_UNSUPPORTED EFIERR(3) +#define EFI_BAD_BUFFER_SIZE EFIERR(4) +#define EFI_BUFFER_TOO_SMALL EFIERR(5) +#define EFI_NOT_READY EFIERR(6) +#define EFI_DEVICE_ERROR EFIERR(7) +#define EFI_WRITE_PROTECTED EFIERR(8) +#define EFI_OUT_OF_RESOURCES EFIERR(9) +#define EFI_VOLUME_CORRUPTED EFIERR(10) +#define EFI_VOLUME_FULL EFIERR(11) +#define EFI_NO_MEDIA EFIERR(12) +#define EFI_MEDIA_CHANGED EFIERR(13) +#define EFI_NOT_FOUND EFIERR(14) +#define EFI_ACCESS_DENIED EFIERR(15) +#define EFI_NO_RESPONSE EFIERR(16) +#define EFI_NO_MAPPING EFIERR(17) +#define EFI_TIMEOUT EFIERR(18) +#define EFI_NOT_STARTED EFIERR(19) +#define EFI_ALREADY_STARTED EFIERR(20) +#define EFI_ABORTED EFIERR(21) +#define EFI_ICMP_ERROR EFIERR(22) +#define EFI_TFTP_ERROR EFIERR(23) +#define EFI_PROTOCOL_ERROR EFIERR(24) + +#define EFI_WARN_UNKOWN_GLYPH EFIWARN(1) +#define EFI_WARN_DELETE_FAILURE EFIWARN(2) +#define EFI_WARN_WRITE_FAILURE EFIWARN(3) +#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4) + +#endif diff --git a/sys/boot/efi/include/efifpswa.h b/sys/boot/efi/include/efifpswa.h new file mode 100644 index 0000000000..db7629cc02 --- /dev/null +++ b/sys/boot/efi/include/efifpswa.h @@ -0,0 +1,43 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efifpswa.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efifpswa.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_FPSWA_H +#define _EFI_FPSWA_H + +/* + * EFI FP SWA Driver (Floating Point Software Assist) + */ + +#define EFI_INTEL_FPSWA \ + { 0xc41b6531, 0x97b9, 0x11d3, 0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +INTERFACE_DECL(_FPSWA_INTERFACE); + +typedef struct _FPSWA_RET { + UINT64 status; + UINT64 err1; + UINT64 err2; + UINT64 err3; +} FPSWA_RET; + +typedef +FPSWA_RET +(EFIAPI *EFI_FPSWA) ( + IN UINTN TrapType, + IN OUT VOID *Bundle, + IN OUT UINT64 *pipsr, + IN OUT UINT64 *pfsr, + IN OUT UINT64 *pisr, + IN OUT UINT64 *ppreds, + IN OUT UINT64 *pifs, + IN OUT VOID *fp_state + ); + +typedef struct _FPSWA_INTERFACE { + UINT32 Revision; + UINT32 Reserved; + EFI_FPSWA Fpswa; +} FPSWA_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efifs.h b/sys/boot/efi/include/efifs.h new file mode 100644 index 0000000000..8fede0b0de --- /dev/null +++ b/sys/boot/efi/include/efifs.h @@ -0,0 +1,119 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efifs.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efifs.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_FS_H +#define _EFI_FS_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efifs.h + +Abstract: + + EFI File System structures + + + +Revision History + +--*/ + + +/* + * EFI Partition header (normaly starts in LBA 1) + */ + +#define EFI_PARTITION_SIGNATURE 0x5053595320494249 +#define EFI_PARTITION_REVISION 0x00010001 +#define MIN_EFI_PARTITION_BLOCK_SIZE 512 +#define EFI_PARTITION_LBA 1 + +typedef struct _EFI_PARTITION_HEADER { + EFI_TABLE_HEADER Hdr; + UINT32 DirectoryAllocationNumber; + UINT32 BlockSize; + EFI_LBA FirstUsableLba; + EFI_LBA LastUsableLba; + EFI_LBA UnusableSpace; + EFI_LBA FreeSpace; + EFI_LBA RootFile; + EFI_LBA SecutiryFile; +} EFI_PARTITION_HEADER; + + +/* + * File header + */ + +#define EFI_FILE_HEADER_SIGNATURE 0x454c494620494249 +#define EFI_FILE_HEADER_REVISION 0x00010000 +#define EFI_FILE_STRING_SIZE 260 + +typedef struct _EFI_FILE_HEADER { + EFI_TABLE_HEADER Hdr; + UINT32 Class; + UINT32 LBALOffset; + EFI_LBA Parent; + UINT64 FileSize; + UINT64 FileAttributes; + EFI_TIME FileCreateTime; + EFI_TIME FileModificationTime; + EFI_GUID VendorGuid; + CHAR16 FileString[EFI_FILE_STRING_SIZE]; +} EFI_FILE_HEADER; + + +/* + * Return the file's first LBAL which is in the same + * logical block as the file header + */ + +#define EFI_FILE_LBAL(a) ((EFI_LBAL *) (((CHAR8 *) (a)) + (a)->LBALOffset)) + +#define EFI_FILE_CLASS_FREE_SPACE 1 +#define EFI_FILE_CLASS_EMPTY 2 +#define EFI_FILE_CLASS_NORMAL 3 + + +/* + * Logical Block Address List - the fundemental block + * description structure + */ + +#define EFI_LBAL_SIGNATURE 0x4c41424c20494249 +#define EFI_LBAL_REVISION 0x00010000 + +typedef struct _EFI_LBAL { + EFI_TABLE_HEADER Hdr; + UINT32 Class; + EFI_LBA Parent; + EFI_LBA Next; + UINT32 ArraySize; + UINT32 ArrayCount; +} EFI_LBAL; + +/* Array size */ +#define EFI_LBAL_ARRAY_SIZE(lbal,offs,blks) \ + (((blks) - (offs) - (lbal)->Hdr.HeaderSize) / sizeof(EFI_RL)) + +/* + * Logical Block run-length + */ + +typedef struct { + EFI_LBA Start; + UINT64 Length; +} EFI_RL; + +/* + * Return the run-length structure from an LBAL header + */ + +#define EFI_LBAL_RL(a) ((EFI_RL*) (((CHAR8 *) (a)) + (a)->Hdr.HeaderSize)) + +#endif diff --git a/sys/boot/arc/lib/time.c b/sys/boot/efi/include/efilib.h similarity index 73% copy from sys/boot/arc/lib/time.c copy to sys/boot/efi/include/efilib.h index 56c48f7875..e945e0055d 100644 --- a/sys/boot/arc/lib/time.c +++ b/sys/boot/efi/include/efilib.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998 Doug Rabson + * Copyright (c) 2000 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,20 +23,17 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/arc/lib/time.c,v 1.2 1999/08/28 00:39:39 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/time.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $FreeBSD: src/sys/boot/efi/include/efilib.h,v 1.3 2002/12/10 20:11:19 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efilib.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ */ -#include -#include -#include "arctypes.h" -#include "arcfuncs.h" +extern EFI_HANDLE IH; +extern EFI_SYSTEM_TABLE *ST; +extern EFI_BOOT_SERVICES *BS; +extern EFI_RUNTIME_SERVICES *RS; -time_t -time(time_t *tloc) -{ - int secs = GetRelativeTime(); - if (tloc) - *tloc = secs; - return secs; -} +void *efi_get_table(EFI_GUID *tbl); +void efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table); + +EFI_STATUS main(int argc, CHAR16 *argv[]); +void exit(EFI_STATUS status); diff --git a/sys/boot/efi/include/efinet.h b/sys/boot/efi/include/efinet.h new file mode 100644 index 0000000000..f391d1d6a0 --- /dev/null +++ b/sys/boot/efi/include/efinet.h @@ -0,0 +1,264 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efinet.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efinet.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFINET_H +#define _EFINET_H + + +/*++ +Copyright (c) 1999 Intel Corporation + +Module Name: + efinet.h + +Abstract: + EFI Simple Network protocol + +Revision History +--*/ + + +#define EFI_SIMPLE_NETWORK_PROTOCOL \ + { 0xA19832B9, 0xAC25, 0x11D3, 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + +INTERFACE_DECL(_EFI_SIMPLE_NETWORK); + +typedef struct { + /* + * Total number of frames received. Includes frames with errors and + * dropped frames. + */ + UINT64 RxTotalFrames; + + /* Number of valid frames received and copied into receive buffers. */ + UINT64 RxGoodFrames; + + /* + * Number of frames below the minimum length for the media. + * This would be <64 for ethernet. + */ + UINT64 RxUndersizeFrames; + + /* + * Number of frames longer than the maxminum length for the + * media. This would be >1500 for ethernet. + */ + UINT64 RxOversizeFrames; + + /* Valid frames that were dropped because receive buffers were full. */ + UINT64 RxDroppedFrames; + + /* Number of valid unicast frames received and not dropped. */ + UINT64 RxUnicastFrames; + + /* Number of valid broadcast frames received and not dropped. */ + UINT64 RxBroadcastFrames; + + /* Number of valid mutlicast frames received and not dropped. */ + UINT64 RxMulticastFrames; + + /* Number of frames w/ CRC or alignment errors. */ + UINT64 RxCrcErrorFrames; + + /* + * Total number of bytes received. Includes frames with errors + * and dropped frames. + */ + UINT64 RxTotalBytes; + + /* Transmit statistics. */ + UINT64 TxTotalFrames; + UINT64 TxGoodFrames; + UINT64 TxUndersizeFrames; + UINT64 TxOversizeFrames; + UINT64 TxDroppedFrames; + UINT64 TxUnicastFrames; + UINT64 TxBroadcastFrames; + UINT64 TxMulticastFrames; + UINT64 TxCrcErrorFrames; + UINT64 TxTotalBytes; + + /* Number of collisions detection on this subnet. */ + UINT64 Collisions; + + /* Number of frames destined for unsupported protocol. */ + UINT64 UnsupportedProtocol; + +} EFI_NETWORK_STATISTICS; + +typedef enum { + EfiSimpleNetworkStopped, + EfiSimpleNetworkStarted, + EfiSimpleNetworkInitialized, + EfiSimpleNetworkMaxState +} EFI_SIMPLE_NETWORK_STATE; + +#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01 +#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02 +#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10 + +#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01 +#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02 +#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04 +#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08 + +#define MAX_MCAST_FILTER_CNT 16 +typedef struct { + UINT32 State; + UINT32 HwAddressSize; + UINT32 MediaHeaderSize; + UINT32 MaxPacketSize; + UINT32 NvRamSize; + UINT32 NvRamAccessSize; + UINT32 ReceiveFilterMask; + UINT32 ReceiveFilterSetting; + UINT32 MaxMCastFilterCount; + UINT32 MCastFilterCount; + EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]; + EFI_MAC_ADDRESS CurrentAddress; + EFI_MAC_ADDRESS BroadcastAddress; + EFI_MAC_ADDRESS PermanentAddress; + UINT8 IfType; + BOOLEAN MacAddressChangeable; + BOOLEAN MultipleTxSupported; + BOOLEAN MediaPresentSupported; + BOOLEAN MediaPresent; +} EFI_SIMPLE_NETWORK_MODE; + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_START) ( + IN struct _EFI_SIMPLE_NETWORK *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STOP) ( + IN struct _EFI_SIMPLE_NETWORK *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RESET) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN ExtendedVerification +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN) ( + IN struct _EFI_SIMPLE_NETWORK *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_NVDATA) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS) ( + IN struct _EFI_SIMPLE_NETWORK *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT) ( + IN struct _EFI_SIMPLE_NETWORK *This, + IN UINTN HeaderSize, + IN UINTN BufferSize, + IN VOID *Buffer, + IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + IN EFI_MAC_ADDRESS *DestAddr OPTIONAL, + IN UINT16 *Protocol OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE) ( + IN struct _EFI_SIMPLE_NETWORK *This, + OUT UINTN *HeaderSize OPTIONAL, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer, + OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL, + OUT UINT16 *Protocol OPTIONAL +); + +#define EFI_SIMPLE_NETWORK_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_SIMPLE_NETWORK { + UINT64 Revision; + EFI_SIMPLE_NETWORK_START Start; + EFI_SIMPLE_NETWORK_STOP Stop; + EFI_SIMPLE_NETWORK_INITIALIZE Initialize; + EFI_SIMPLE_NETWORK_RESET Reset; + EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown; + EFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters; + EFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress; + EFI_SIMPLE_NETWORK_STATISTICS Statistics; + EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC MCastIpToMac; + EFI_SIMPLE_NETWORK_NVDATA NvData; + EFI_SIMPLE_NETWORK_GET_STATUS GetStatus; + EFI_SIMPLE_NETWORK_TRANSMIT Transmit; + EFI_SIMPLE_NETWORK_RECEIVE Receive; + EFI_EVENT WaitForPacket; + EFI_SIMPLE_NETWORK_MODE *Mode; +} EFI_SIMPLE_NETWORK; + +#endif /* _EFINET_H */ diff --git a/sys/boot/efi/include/efipart.h b/sys/boot/efi/include/efipart.h new file mode 100644 index 0000000000..f4c9d4acba --- /dev/null +++ b/sys/boot/efi/include/efipart.h @@ -0,0 +1,61 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efipart.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efipart.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_PART_H +#define _EFI_PART_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efipart.h + +Abstract: + Info about disk partitions and Master Boot Records + + + + +Revision History + +--*/ + +#define EFI_PARTITION 0xef +#define MBR_SIZE 512 + +#pragma pack(1) + +typedef struct { + UINT8 BootIndicator; + UINT8 StartHead; + UINT8 StartSector; + UINT8 StartTrack; + UINT8 OSIndicator; + UINT8 EndHead; + UINT8 EndSector; + UINT8 EndTrack; + UINT8 StartingLBA[4]; + UINT8 SizeInLBA[4]; +} MBR_PARTITION_RECORD; + +#define EXTRACT_UINT32(D) (UINT32)(D[0] | (D[1] << 8) | (D[2] << 16) | (D[3] << 24)) + +#define MBR_SIGNATURE 0xaa55 +#define MIN_MBR_DEVICE_SIZE 0x80000 +#define MBR_ERRATA_PAD 0x40000 /* 128 MB */ + +#define MAX_MBR_PARTITIONS 4 +typedef struct { + UINT8 BootStrapCode[440]; + UINT8 UniqueMbrSignature[4]; + UINT8 Unknown[2]; + MBR_PARTITION_RECORD Partition[MAX_MBR_PARTITIONS]; + UINT16 Signature; +} MASTER_BOOT_RECORD; +#pragma pack() + + +#endif diff --git a/sys/boot/efi/include/efiprot.h b/sys/boot/efi/include/efiprot.h new file mode 100644 index 0000000000..270e75feb0 --- /dev/null +++ b/sys/boot/efi/include/efiprot.h @@ -0,0 +1,554 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efiprot.h,v 1.3 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efiprot.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_PROT_H +#define _EFI_PROT_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiprot.h + +Abstract: + + EFI Protocols + + + +Revision History + +--*/ + +/* + * Device Path protocol + */ + +#define DEVICE_PATH_PROTOCOL \ + { 0x9576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + + +/* + * Block IO protocol + */ + +#define BLOCK_IO_PROTOCOL \ + { 0x964e5b21, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } +#define EFI_BLOCK_IO_INTERFACE_REVISION 0x00010000 + +INTERFACE_DECL(_EFI_BLOCK_IO); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_RESET) ( + IN struct _EFI_BLOCK_IO *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_READ) ( + IN struct _EFI_BLOCK_IO *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_WRITE) ( + IN struct _EFI_BLOCK_IO *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_FLUSH) ( + IN struct _EFI_BLOCK_IO *This + ); + + + +typedef struct { + UINT32 MediaId; + BOOLEAN RemovableMedia; + BOOLEAN MediaPresent; + + BOOLEAN LogicalPartition; + BOOLEAN ReadOnly; + BOOLEAN WriteCaching; + + UINT32 BlockSize; + UINT32 IoAlign; + + EFI_LBA LastBlock; +} EFI_BLOCK_IO_MEDIA; + +typedef struct _EFI_BLOCK_IO { + UINT64 Revision; + + EFI_BLOCK_IO_MEDIA *Media; + + EFI_BLOCK_RESET Reset; + EFI_BLOCK_READ ReadBlocks; + EFI_BLOCK_WRITE WriteBlocks; + EFI_BLOCK_FLUSH FlushBlocks; + +} EFI_BLOCK_IO; + + + +/* + * Disk Block IO protocol + */ + +#define DISK_IO_PROTOCOL \ + { 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } +#define EFI_DISK_IO_INTERFACE_REVISION 0x00010000 + +INTERFACE_DECL(_EFI_DISK_IO); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_READ) ( + IN struct _EFI_DISK_IO *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_WRITE) ( + IN struct _EFI_DISK_IO *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +typedef struct _EFI_DISK_IO { + UINT64 Revision; + EFI_DISK_READ ReadDisk; + EFI_DISK_WRITE WriteDisk; +} EFI_DISK_IO; + + +/* + * Simple filesystem protocol + */ + +#define SIMPLE_FILE_SYSTEM_PROTOCOL \ + { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_EFI_FILE_IO_INTERFACE); +INTERFACE_DECL(_EFI_FILE_HANDLE); + +typedef +EFI_STATUS +(EFIAPI *EFI_VOLUME_OPEN) ( + IN struct _EFI_FILE_IO_INTERFACE *This, + OUT struct _EFI_FILE_HANDLE **Root + ); + +#define EFI_FILE_IO_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_FILE_IO_INTERFACE { + UINT64 Revision; + EFI_VOLUME_OPEN OpenVolume; +} EFI_FILE_IO_INTERFACE; + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_OPEN) ( + IN struct _EFI_FILE_HANDLE *File, + OUT struct _EFI_FILE_HANDLE **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/* Open modes */ +#define EFI_FILE_MODE_READ 0x0000000000000001 +#define EFI_FILE_MODE_WRITE 0x0000000000000002 +#define EFI_FILE_MODE_CREATE 0x8000000000000000 + +/* File attributes */ +#define EFI_FILE_READ_ONLY 0x0000000000000001 +#define EFI_FILE_HIDDEN 0x0000000000000002 +#define EFI_FILE_SYSTEM 0x0000000000000004 +#define EFI_FILE_RESERVIED 0x0000000000000008 +#define EFI_FILE_DIRECTORY 0x0000000000000010 +#define EFI_FILE_ARCHIVE 0x0000000000000020 +#define EFI_FILE_VALID_ATTR 0x0000000000000037 + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_CLOSE) ( + IN struct _EFI_FILE_HANDLE *File + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_DELETE) ( + IN struct _EFI_FILE_HANDLE *File + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_READ) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_WRITE) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_POSITION) ( + IN struct _EFI_FILE_HANDLE *File, + IN UINT64 Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_POSITION) ( + IN struct _EFI_FILE_HANDLE *File, + OUT UINT64 *Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_INFO) ( + IN struct _EFI_FILE_HANDLE *File, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_INFO) ( + IN struct _EFI_FILE_HANDLE *File, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_FLUSH) ( + IN struct _EFI_FILE_HANDLE *File + ); + + + +#define EFI_FILE_HANDLE_REVISION 0x00010000 +typedef struct _EFI_FILE_HANDLE { + UINT64 Revision; + EFI_FILE_OPEN Open; + EFI_FILE_CLOSE Close; + EFI_FILE_DELETE Delete; + EFI_FILE_READ Read; + EFI_FILE_WRITE Write; + EFI_FILE_GET_POSITION GetPosition; + EFI_FILE_SET_POSITION SetPosition; + EFI_FILE_GET_INFO GetInfo; + EFI_FILE_SET_INFO SetInfo; + EFI_FILE_FLUSH Flush; +} EFI_FILE, *EFI_FILE_HANDLE; + + +/* + * File information types + */ + +#define EFI_FILE_INFO_ID \ + { 0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +typedef struct { + UINT64 Size; + UINT64 FileSize; + UINT64 PhysicalSize; + EFI_TIME CreateTime; + EFI_TIME LastAccessTime; + EFI_TIME ModificationTime; + UINT64 Attribute; + CHAR16 FileName[1]; +} EFI_FILE_INFO; + +/* + * The FileName field of the EFI_FILE_INFO data structure is variable length. + * Whenever code needs to know the size of the EFI_FILE_INFO data structure, + * it needs to be the size of the data structure without the FileName field. + * The following macro computes this size correctly no matter how big the + * FileName array is declared. This is required to make the EFI_FILE_INFO + * data structure ANSI compliant. + */ + +#define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName) + +#define EFI_FILE_SYSTEM_INFO_ID \ + { 0x9576e93, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +typedef struct { + UINT64 Size; + BOOLEAN ReadOnly; + UINT64 VolumeSize; + UINT64 FreeSpace; + UINT32 BlockSize; + CHAR16 VolumeLabel[1]; +} EFI_FILE_SYSTEM_INFO; + +/* + * The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is + * variable length. Whenever code needs to know the size of the + * EFI_FILE_SYSTEM_INFO data structure, it needs to be the size of the data + * structure without the VolumeLable field. The following macro computes + * this size correctly no matter how big the VolumeLable array is declared. + * This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI + * compilant. + */ + +#define SIZE_OF_EFI_FILE_SYSTEM_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO,VolumeLabel) + +#define EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID \ + { 0xDB47D7D3,0xFE81, 0x11d3, 0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + +typedef struct { + CHAR16 VolumeLabel[1]; +} EFI_FILE_SYSTEM_VOLUME_LABEL_INFO; + +#define SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_VOLUME_LABEL_INFO,VolumeLabel) + +/* + * Load file protocol + */ + +#define LOAD_FILE_PROTOCOL \ + { 0x56EC3091, 0x954C, 0x11d2, 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } + +INTERFACE_DECL(_EFI_LOAD_FILE_INTERFACE); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOAD_FILE) ( + IN struct _EFI_LOAD_FILE_INTERFACE *This, + IN EFI_DEVICE_PATH *FilePath, + IN BOOLEAN BootPolicy, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL + ); + +typedef struct _EFI_LOAD_FILE_INTERFACE { + EFI_LOAD_FILE LoadFile; +} EFI_LOAD_FILE_INTERFACE; + + +/* + * Device IO protocol + */ + +#define DEVICE_IO_PROTOCOL \ + { 0xaf6ac311, 0x84c3, 0x11d2, 0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +INTERFACE_DECL(_EFI_DEVICE_IO_INTERFACE); + +typedef enum { + IO_UINT8, + IO_UINT16, + IO_UINT32, + IO_UINT64, +/* + * Specification Change: Copy from MMIO to MMIO vs. MMIO to buffer, buffer to + * MMIO + */ + MMIO_COPY_UINT8, + MMIO_COPY_UINT16, + MMIO_COPY_UINT32, + MMIO_COPY_UINT64 +} EFI_IO_WIDTH; + +#define EFI_PCI_ADDRESS(_bus,_dev,_func) \ + ( (UINT64) ( (((UINTN)_bus) << 24) + (((UINTN)_dev) << 16) + (((UINTN)_func) << 8) ) ) + + +typedef +EFI_STATUS +(EFIAPI *EFI_DEVICE_IO) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +typedef struct { + EFI_DEVICE_IO Read; + EFI_DEVICE_IO Write; +} EFI_IO_ACCESS; + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_DEVICE_PATH) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN UINT64 Address, + IN OUT EFI_DEVICE_PATH **PciDevicePath + ); + +typedef enum { + EfiBusMasterRead, + EfiBusMasterWrite, + EfiBusMasterCommonBuffer +} EFI_IO_OPERATION_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_MAP) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN EFI_IO_OPERATION_TYPE Operation, + IN EFI_PHYSICAL_ADDRESS *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_UNMAP) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN VOID *Mapping + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_ALLOCATE_BUFFER) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *HostAddress + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FLUSH) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FREE_BUFFER) ( + IN struct _EFI_DEVICE_IO_INTERFACE *This, + IN UINTN Pages, + IN EFI_PHYSICAL_ADDRESS HostAddress + ); + +typedef struct _EFI_DEVICE_IO_INTERFACE { + EFI_IO_ACCESS Mem; + EFI_IO_ACCESS Io; + EFI_IO_ACCESS Pci; + EFI_IO_MAP Map; + EFI_PCI_DEVICE_PATH PciDevicePath; + EFI_IO_UNMAP Unmap; + EFI_IO_ALLOCATE_BUFFER AllocateBuffer; + EFI_IO_FLUSH Flush; + EFI_IO_FREE_BUFFER FreeBuffer; +} EFI_DEVICE_IO_INTERFACE; + + +/* + * Unicode Collation protocol + */ + +#define UNICODE_COLLATION_PROTOCOL \ + { 0x1d85cd7f, 0xf43d, 0x11d2, 0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +#define UNICODE_BYTE_ORDER_MARK (CHAR16)(0xfeff) + +INTERFACE_DECL(_EFI_UNICODE_COLLATION_INTERFACE); + +typedef +INTN +(EFIAPI *EFI_UNICODE_STRICOLL) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *s1, + IN CHAR16 *s2 + ); + +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_METAIMATCH) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_STRLWR) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN OUT CHAR16 *Str + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_STRUPR) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN OUT CHAR16 *Str + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_FATTOSTR) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_STRTOFAT) ( + IN struct _EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); + + +typedef struct _EFI_UNICODE_COLLATION_INTERFACE { + + /* general */ + EFI_UNICODE_STRICOLL StriColl; + EFI_UNICODE_METAIMATCH MetaiMatch; + EFI_UNICODE_STRLWR StrLwr; + EFI_UNICODE_STRUPR StrUpr; + + /* for supporting fat volumes */ + EFI_UNICODE_FATTOSTR FatToStr; + EFI_UNICODE_STRTOFAT StrToFat; + + CHAR8 *SupportedLanguages; +} EFI_UNICODE_COLLATION_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efipxebc.h b/sys/boot/efi/include/efipxebc.h new file mode 100644 index 0000000000..b3b198df18 --- /dev/null +++ b/sys/boot/efi/include/efipxebc.h @@ -0,0 +1,462 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efipxebc.h,v 1.2 2002/05/19 03:17:20 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efipxebc.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFIPXEBC_H +#define _EFIPXEBC_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efipxebc.h + +Abstract: + + EFI PXE Base Code Protocol + + + +Revision History + +--*/ + +/* + * PXE Base Code protocol + */ + +#define EFI_PXE_BASE_CODE_PROTOCOL \ + { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } + +INTERFACE_DECL(_EFI_PXE_BASE_CODE); + +#define DEFAULT_TTL 4 +#define DEFAULT_ToS 0 + +/* + * Address definitions + */ + +typedef union { + UINT32 Addr[4]; + EFI_IPv4_ADDRESS v4; + EFI_IPv6_ADDRESS v6; +} EFI_IP_ADDRESS; + +typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT; + +/* + * Packet definitions + */ + +typedef struct { + UINT8 BootpOpcode; + UINT8 BootpHwType; + UINT8 BootpHwAddrLen; + UINT8 BootpGateHops; + UINT32 BootpIdent; + UINT16 BootpSeconds; + UINT16 BootpFlags; + UINT8 BootpCiAddr[4]; + UINT8 BootpYiAddr[4]; + UINT8 BootpSiAddr[4]; + UINT8 BootpGiAddr[4]; + UINT8 BootpHwAddr[16]; + UINT8 BootpSrvName[64]; + UINT8 BootpBootFile[128]; + UINT32 DhcpMagik; + UINT8 DhcpOptions[56]; +} EFI_PXE_BASE_CODE_DHCPV4_PACKET; + +typedef union { + UINT8 Raw[1472]; + EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4; +} EFI_PXE_BASE_CODE_PACKET; + +typedef struct { + UINT8 Type; + UINT8 Code; + UINT16 Checksum; + union { + UINT32 reserved; + UINT32 Mtu; + UINT32 Pointer; + struct { + UINT16 Identifier; + UINT16 Sequence; + } Echo; + } u; + UINT8 Data[494]; +} EFI_PXE_BASE_CODE_ICMP_ERROR; + +typedef struct { + UINT8 ErrorCode; + CHAR8 ErrorString[127]; +} EFI_PXE_BASE_CODE_TFTP_ERROR; + +/* + * IP Receive Filter definitions + */ +#define EFI_PXE_BASE_CODE_MAX_IPCNT 8 +typedef struct { + UINT8 Filters; + UINT8 IpCnt; + UINT16 reserved; + EFI_IP_ADDRESS IpList[EFI_PXE_BASE_CODE_MAX_IPCNT]; +} EFI_PXE_BASE_CODE_IP_FILTER; + +#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP 0x0001 +#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST 0x0002 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS 0x0004 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST 0x0008 + +/* + * ARP Cache definitions + */ + +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_MAC_ADDRESS MacAddr; +} EFI_PXE_BASE_CODE_ARP_ENTRY; + +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_IP_ADDRESS SubnetMask; + EFI_IP_ADDRESS GwAddr; +} EFI_PXE_BASE_CODE_ROUTE_ENTRY; + +/* + * UDP definitions + */ + +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP 0x0001 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT 0x0002 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP 0x0004 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT 0x0008 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER 0x0010 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT 0x0020 + +/* + * Discover() definitions + */ + +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS 1 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM 2 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI 3 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NEC_ESMPRO 4 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_WSoD 5 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_LCCM 6 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_CA_UNICENTER_TNG 7 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_HP_OPENVIEW 8 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_9 9 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_10 10 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_11 11 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NOT_USED_12 12 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_INSTALL 13 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT 14 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REMBO 15 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BEOBOOT 16 +/* + * 17 through 32767 are reserved + * 32768 through 65279 are for vendor use + * 65280 through 65534 are reserved + */ +#define EFI_PXE_BASE_CODE_BOOT_TYPE_PXETEST 65535 + +#define EFI_PXE_BASE_CODE_BOOT_LAYER_MASK 0x7FFF +#define EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL 0x0000 + + +typedef struct { + UINT16 Type; + BOOLEAN AcceptAnyResponse; + UINT8 Reserved; + EFI_IP_ADDRESS IpAddr; +} EFI_PXE_BASE_CODE_SRVLIST; + +typedef struct { + BOOLEAN UseMCast; + BOOLEAN UseBCast; + BOOLEAN UseUCast; + BOOLEAN MustUseList; + EFI_IP_ADDRESS ServerMCastIp; + UINT16 IpCnt; + EFI_PXE_BASE_CODE_SRVLIST SrvList[1]; +} EFI_PXE_BASE_CODE_DISCOVER_INFO; + +/* + * Mtftp() definitions + */ + +typedef enum { + EFI_PXE_BASE_CODE_TFTP_FIRST, + EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_TFTP_READ_FILE, + EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, + EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_MTFTP_READ_FILE, + EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_LAST +} EFI_PXE_BASE_CODE_TFTP_OPCODE; + +typedef struct { + EFI_IP_ADDRESS MCastIp; + EFI_PXE_BASE_CODE_UDP_PORT CPort; + EFI_PXE_BASE_CODE_UDP_PORT SPort; + UINT16 ListenTimeout; + UINT16 TransmitTimeout; +} EFI_PXE_BASE_CODE_MTFTP_INFO; + +/* + * PXE Base Code Mode structure + */ + +#define EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8 +#define EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8 + +typedef struct { + BOOLEAN Started; + BOOLEAN Ipv6Available; + BOOLEAN Ipv6Supported; + BOOLEAN UsingIpv6; + BOOLEAN BisSupported; + BOOLEAN BisDetected; + BOOLEAN AutoArp; + BOOLEAN SendGUID; + BOOLEAN DhcpDiscoverValid; + BOOLEAN DhcpAckReceived; + BOOLEAN ProxyOfferReceived; + BOOLEAN PxeDiscoverValid; + BOOLEAN PxeReplyReceived; + BOOLEAN PxeBisReplyReceived; + BOOLEAN IcmpErrorReceived; + BOOLEAN TftpErrorReceived; + BOOLEAN MakeCallbacks; + UINT8 TTL; + UINT8 ToS; + EFI_IP_ADDRESS StationIp; + EFI_IP_ADDRESS SubnetMask; + EFI_PXE_BASE_CODE_PACKET DhcpDiscover; + EFI_PXE_BASE_CODE_PACKET DhcpAck; + EFI_PXE_BASE_CODE_PACKET ProxyOffer; + EFI_PXE_BASE_CODE_PACKET PxeDiscover; + EFI_PXE_BASE_CODE_PACKET PxeReply; + EFI_PXE_BASE_CODE_PACKET PxeBisReply; + EFI_PXE_BASE_CODE_IP_FILTER IpFilter; + UINT32 ArpCacheEntries; + EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache[EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; + UINT32 RouteTableEntries; + EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; + EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError; + EFI_PXE_BASE_CODE_TFTP_ERROR TftpError; +} EFI_PXE_BASE_CODE_MODE; + +/* + * PXE Base Code Interface Function definitions + */ + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_START) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN BOOLEAN UseIpv6 + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_STOP) ( + IN struct _EFI_PXE_BASE_CODE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DHCP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN BOOLEAN SortOffers + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DISCOVER) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN UINT16 Type, + IN UINT16 *Layer, + IN BOOLEAN UseBis, + IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_MTFTP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, + IN OUT VOID *BufferPtr OPTIONAL, + IN BOOLEAN Overwrite, + IN OUT UINTN *BufferSize, + IN UINTN *BlockSize OPTIONAL, + IN EFI_IP_ADDRESS *ServerIp, + IN UINT8 *Filename, + IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL, + IN BOOLEAN DontUseBuffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_WRITE) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN UINT16 OpFlags, + IN EFI_IP_ADDRESS *DestIp, + IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, + IN EFI_IP_ADDRESS *GatewayIp, OPTIONAL + IN EFI_IP_ADDRESS *SrcIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL + IN UINTN *HeaderSize, OPTIONAL + IN VOID *HeaderPtr, OPTIONAL + IN UINTN *BufferSize, + IN VOID *BufferPtr + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_READ) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN UINT16 OpFlags, + IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL + IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL + IN UINTN *HeaderSize, OPTIONAL + IN VOID *HeaderPtr, OPTIONAL + IN OUT UINTN *BufferSize, + IN VOID *BufferPtr + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_IP_FILTER) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_ARP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_IP_ADDRESS *IpAddr, + IN EFI_MAC_ADDRESS *MacAddr OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PARAMETERS) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN BOOLEAN *NewAutoArp, OPTIONAL + IN BOOLEAN *NewSendGUID, OPTIONAL + IN UINT8 *NewTTL, OPTIONAL + IN UINT8 *NewToS, OPTIONAL + IN BOOLEAN *NewMakeCallback OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_STATION_IP) ( + IN struct _EFI_PXE_BASE_CODE *This, + IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL + IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PACKETS) ( + IN struct _EFI_PXE_BASE_CODE *This, + BOOLEAN *NewDhcpDiscoverValid, OPTIONAL + BOOLEAN *NewDhcpAckReceived, OPTIONAL + BOOLEAN *NewProxyOfferReceived, OPTIONAL + BOOLEAN *NewPxeDiscoverValid, OPTIONAL + BOOLEAN *NewPxeReplyReceived, OPTIONAL + BOOLEAN *NewPxeBisReplyReceived,OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpDiscover, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpAck, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewProxyOffer, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeDiscover, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeReply, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeBisReply OPTIONAL + ); + +/* + * PXE Base Code Protocol structure + */ + +#define EFI_PXE_BASE_CODE_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_PXE_BASE_CODE { + UINT64 Revision; + EFI_PXE_BASE_CODE_START Start; + EFI_PXE_BASE_CODE_STOP Stop; + EFI_PXE_BASE_CODE_DHCP Dhcp; + EFI_PXE_BASE_CODE_DISCOVER Discover; + EFI_PXE_BASE_CODE_MTFTP Mtftp; + EFI_PXE_BASE_CODE_UDP_WRITE UdpWrite; + EFI_PXE_BASE_CODE_UDP_READ UdpRead; + EFI_PXE_BASE_CODE_SET_IP_FILTER SetIpFilter; + EFI_PXE_BASE_CODE_ARP Arp; + EFI_PXE_BASE_CODE_SET_PARAMETERS SetParameters; + EFI_PXE_BASE_CODE_SET_STATION_IP SetStationIp; + EFI_PXE_BASE_CODE_SET_PACKETS SetPackets; + EFI_PXE_BASE_CODE_MODE *Mode; +} EFI_PXE_BASE_CODE; + +/* + * Call Back Definitions + */ + +#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL \ + { 0x245dca21, 0xfb7b, 0x11d3, 0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } + +/* + * Revision Number + */ + +#define EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION 0x00010000 + +INTERFACE_DECL(_EFI_PXE_BASE_CODE_CALLBACK); + +typedef enum { + EFI_PXE_BASE_CODE_FUNCTION_FIRST, + EFI_PXE_BASE_CODE_FUNCTION_DHCP, + EFI_PXE_BASE_CODE_FUNCTION_DISCOVER, + EFI_PXE_BASE_CODE_FUNCTION_MTFTP, + EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE, + EFI_PXE_BASE_CODE_FUNCTION_UDP_READ, + EFI_PXE_BASE_CODE_FUNCTION_ARP, + EFI_PXE_BASE_CODE_FUNCTION_IGMP, + EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST +} EFI_PXE_BASE_CODE_FUNCTION; + +typedef enum { + EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST +} EFI_PXE_BASE_CODE_CALLBACK_STATUS; + +typedef +EFI_PXE_BASE_CODE_CALLBACK_STATUS +(EFIAPI *EFI_PXE_CALLBACK) ( + IN struct _EFI_PXE_BASE_CODE_CALLBACK *This, + IN EFI_PXE_BASE_CODE_FUNCTION Function, + IN BOOLEAN Received, + IN UINT32 PacketLen, + IN EFI_PXE_BASE_CODE_PACKET *Packet OPTIONAL + ); + +typedef struct _EFI_PXE_BASE_CODE_CALLBACK { + UINT64 Revision; + EFI_PXE_CALLBACK Callback; +} EFI_PXE_BASE_CODE_CALLBACK; + +#endif /* _EFIPXEBC_H */ diff --git a/sys/boot/efi/include/efiser.h b/sys/boot/efi/include/efiser.h new file mode 100644 index 0000000000..763de97a48 --- /dev/null +++ b/sys/boot/efi/include/efiser.h @@ -0,0 +1,135 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efiser.h,v 1.2 2002/05/19 03:17:21 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/efiser.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFI_SER_H +#define _EFI_SER_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiser.h + +Abstract: + + EFI serial protocol + +Revision History + +--*/ + +/* + * Serial protocol + */ + +#define SERIAL_IO_PROTOCOL \ + { 0xBB25CF6F, 0xF1D4, 0x11D2, 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD } + +INTERFACE_DECL(_SERIAL_IO_INTERFACE); + +typedef enum { + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} EFI_PARITY_TYPE; + +typedef enum { + DefaultStopBits, + OneStopBit, + OneFiveStopBits, + TwoStopBits +} EFI_STOP_BITS_TYPE; + +#define EFI_SERIAL_CLEAR_TO_SEND 0x0010 +#define EFI_SERIAL_DATA_SET_READY 0x0020 +#define EFI_SERIAL_RING_INDICATE 0x0040 +#define EFI_SERIAL_CARRIER_DETECT 0x0080 +#define EFI_SERIAL_REQUEST_TO_SEND 0x0002 +#define EFI_SERIAL_DATA_TERMINAL_READY 0x0001 +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x0100 +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x0200 +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x1000 +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x2000 +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x4000 + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_RESET) ( + IN struct _SERIAL_IO_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_ATTRIBUTES) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN UINT32 Control + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_GET_CONTROL_BITS) ( + IN struct _SERIAL_IO_INTERFACE *This, + OUT UINT32 *Control + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_WRITE) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_READ) ( + IN struct _SERIAL_IO_INTERFACE *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef struct { + UINT32 ControlMask; + + /* current Attributes. */ + UINT32 Timeout; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + UINT32 DataBits; + UINT32 Parity; + UINT32 StopBits; +} SERIAL_IO_MODE; + +#define SERIAL_IO_INTERFACE_REVISION 0x00010000 + +typedef struct _SERIAL_IO_INTERFACE { + UINT32 Revision; + EFI_SERIAL_RESET Reset; + EFI_SERIAL_SET_ATTRIBUTES SetAttributes; + EFI_SERIAL_SET_CONTROL_BITS SetControl; + EFI_SERIAL_GET_CONTROL_BITS GetControl; + EFI_SERIAL_WRITE Write; + EFI_SERIAL_READ Read; + + SERIAL_IO_MODE *Mode; +} SERIAL_IO_INTERFACE; + +#endif diff --git a/sys/boot/efi/include/efistdarg.h b/sys/boot/efi/include/efistdarg.h new file mode 100644 index 0000000000..ae1e455f84 --- /dev/null +++ b/sys/boot/efi/include/efistdarg.h @@ -0,0 +1,35 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/efistdarg.h,v 1.1 2001/06/09 16:49:49 dfr Exp $ + * $DragonFly: src/sys/boot/efi/include/efistdarg.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +#ifndef _EFISTDARG_H_ +#define _EFISTDARG_H_ + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(UINTN) - 1) & ~(sizeof(UINTN) - 1) ) + +typedef CHAR8 * va_list; + +#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) +#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#define va_end(ap) ( ap = (va_list)0 ) + + +#endif /* _INC_STDARG */ diff --git a/sys/boot/efi/include/i386/efibind.h b/sys/boot/efi/include/i386/efibind.h new file mode 100644 index 0000000000..98ac7bc89b --- /dev/null +++ b/sys/boot/efi/include/i386/efibind.h @@ -0,0 +1,252 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/i386/efibind.h,v 1.2 2002/05/19 03:17:22 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/i386/efibind.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#pragma pack() + + +/* + * Basic int types of various widths + */ + +#if (__STDC_VERSION__ < 199901L ) + +/* No ANSI C 1999/2000 stdint.h integer width declarations */ + + #if _MSC_EXTENSIONS + +/* Use Microsoft C compiler integer width declarations */ + + typedef unsigned __int64 uint64_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef __int32 int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + #ifdef UNIX_LP64 + +/* Use LP64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long uint64_t; + typedef long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + +/* Assume P64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #endif + #endif +#endif + +/* + * Basic EFI types of various widths + */ + +typedef uint64_t UINT64; +typedef int64_t INT64; + +#ifndef _BASETSD_H_ + typedef uint32_t UINT32; + typedef int32_t INT32; +#endif + +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; + + +#undef VOID +#define VOID void + + +typedef int32_t INTN; +typedef uint32_t UINTN; + +#ifdef EFI_NT_EMULATOR + #define POST_CODE(_Data) +#else + #ifdef EFI_DEBUG +#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al + #else + #define POST_CODE(_Data) + #endif +#endif + +#define EFIERR(a) (0x80000000 | a) +#define EFI_ERROR_MASK 0x80000000 +#define EFIERR_OEM(a) (0xc0000000 | a) + + +#define BAD_POINTER 0xFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFF + +#ifdef EFI_NT_EMULATOR + #define BREAKPOINT() __asm { int 3 } +#else + #define BREAKPOINT() while (TRUE); +#endif + +/* + * Pointers must be aligned to these address to function + */ + +#define MIN_ALIGNMENT_SIZE 4 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +/* + * Define macros to build data structure signatures from characters. + */ + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +/* + * To export & import functions in the EFI emulator environment + */ + +#if EFI_NT_EMULATOR + #define EXPORTAPI __declspec( dllexport ) +#else + #define EXPORTAPI +#endif + + +/* + * EFIAPI - prototype calling convention for EFI function pointers + * BOOTSERVICE - prototype for implementation of a boot service interface + * RUNTIMESERVICE - prototype for implementation of a runtime service interface + * RUNTIMEFUNCTION - prototype for implementation of a runtime function that + * is not a service + * RUNTIME_CODE - pragma macro for declaring runtime code + */ + +/* Forces EFI calling conventions reguardless of compiler options */ +#ifndef EFIAPI + #if _MSC_EXTENSIONS + #define EFIAPI __cdecl + #else + #define EFIAPI + #endif +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE() + +#ifdef EFI_NT_EMULATOR + +/* + * To help ensure proper coding of integrated drivers, they are + * compiled as DLLs. In NT they require a dll init entry pointer. + * The macro puts a stub entry point into the DLL so it will load. + */ + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + __stdcall \ + _DllMainCRTStartup ( \ + UINTN Inst, \ + UINTN reason_for_call, \ + VOID *rserved \ + ) \ + { \ + return 1; \ + } \ + \ + int \ + EXPORTAPI \ + __cdecl \ + InitializeDriver ( \ + void *ImageHandle, \ + void *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, SystemTable); \ + } + + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, NULL) + +#else /* EFI_NT_EMULATOR */ + +/* + * When build similiar to FW, then link everything together as + * one big module. + */ + + #define EFI_DRIVER_ENTRY_POINT(InitFunction) + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +#endif /* EFI_FW_NT */ + +/* + * Some compilers don't support the forward reference construct: + * typedef struct XXXXX + * + * The following macro provide a workaround for such cases. + */ +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#define INTERFACE_DECL(x) typedef struct x +#endif + +#if _MSC_EXTENSIONS +#pragma warning ( disable : 4731 ) +#endif + diff --git a/sys/boot/efi/include/i386/pe.h b/sys/boot/efi/include/i386/pe.h new file mode 100644 index 0000000000..8bcf570ca7 --- /dev/null +++ b/sys/boot/efi/include/i386/pe.h @@ -0,0 +1,595 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/i386/pe.h,v 1.1 2001/06/09 16:49:50 dfr Exp $ + * $DragonFly: src/sys/boot/efi/include/i386/pe.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +/* + PE32+ header file + */ +#ifndef _PE_H +#define _PE_H + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + UINT16 ne_magic; // Magic number + UINT8 ne_ver; // Version number + UINT8 ne_rev; // Revision number + UINT16 ne_enttab; // Offset of Entry Table + UINT16 ne_cbenttab; // Number of bytes in Entry Table + UINT32 ne_crc; // Checksum of whole file + UINT16 ne_flags; // Flag UINT16 + UINT16 ne_autodata; // Automatic data segment number + UINT16 ne_heap; // Initial heap allocation + UINT16 ne_stack; // Initial stack allocation + UINT32 ne_csip; // Initial CS:IP setting + UINT32 ne_sssp; // Initial SS:SP setting + UINT16 ne_cseg; // Count of file segments + UINT16 ne_cmod; // Entries in Module Reference Table + UINT16 ne_cbnrestab; // Size of non-resident name table + UINT16 ne_segtab; // Offset of Segment Table + UINT16 ne_rsrctab; // Offset of Resource Table + UINT16 ne_restab; // Offset of resident name table + UINT16 ne_modtab; // Offset of Module Reference Table + UINT16 ne_imptab; // Offset of Imported Names Table + UINT32 ne_nrestab; // Offset of Non-resident Names Table + UINT16 ne_cmovent; // Count of movable entries + UINT16 ne_align; // Segment alignment shift count + UINT16 ne_cres; // Count of resource segments + UINT8 ne_exetyp; // Target Operating system + UINT8 ne_flagsothers; // Other .EXE flags + UINT16 ne_pretthunks; // offset to return thunks + UINT16 ne_psegrefbytes; // offset to segment ref. bytes + UINT16 ne_swaparea; // Minimum code swap area size + UINT16 ne_expver; // Expected Windows version number + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +// +// File header format. +// + +typedef struct _IMAGE_FILE_HEADER { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +// +// Optional header format. +// + +typedef struct _IMAGE_OPTIONAL_HEADER { + // + // Standard fields. + // + + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + + // + // NT additional fields. + // + + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Reserved1; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 + +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS { + UINT32 Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((UINT32)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem. + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// Symbol format. +// + + +#define IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// + +#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common. +#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value. +#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item. + +// +// Type (fundamental) values. +// + +#define IMAGE_SYM_TYPE_NULL 0 // no type. +#define IMAGE_SYM_TYPE_VOID 1 // +#define IMAGE_SYM_TYPE_CHAR 2 // type character. +#define IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define IMAGE_SYM_TYPE_INT 4 // +#define IMAGE_SYM_TYPE_LONG 5 // +#define IMAGE_SYM_TYPE_FLOAT 6 // +#define IMAGE_SYM_TYPE_DOUBLE 7 // +#define IMAGE_SYM_TYPE_STRUCT 8 // +#define IMAGE_SYM_TYPE_UNION 9 // +#define IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define IMAGE_SYM_TYPE_BYTE 12 // +#define IMAGE_SYM_TYPE_WORD 13 // +#define IMAGE_SYM_TYPE_UINT 14 // +#define IMAGE_SYM_TYPE_DWORD 15 // + +// +// Type (derived) values. +// + +#define IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define IMAGE_SYM_DTYPE_POINTER 1 // pointer. +#define IMAGE_SYM_DTYPE_FUNCTION 2 // function. +#define IMAGE_SYM_DTYPE_ARRAY 3 // array. + +// +// Storage classes. +// + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +// new +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// type packing constants + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +// MACROS + +// +// Communal selection types. +// + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + + +// +// Relocation format. +// + +typedef struct _IMAGE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} IMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// + +#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +// +// MIPS relocation types. +// + +#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +// +// Alpha Relocation types. +// + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +// +// IBM PowerPC relocation types. +// + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP +#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address +#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address +#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute) +#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address +#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword) +#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative) +#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative) +#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base +#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword) + +#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base +#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr) +#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number +#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code +#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction + +#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type + +// Flag bits in IMAGE_RELOCATION.TYPE + +#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it +#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken +#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc) + +// +// Based relocation format. +// + +typedef struct _IMAGE_BASE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +// UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// +// Line number format. +// + +typedef struct _IMAGE_LINENUMBER { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} IMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 *AddressOfFunctions; + UINT32 *AddressOfNames; + UINT32 *AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +typedef struct _IMAGE_IMPORT_BY_NAME { + UINT16 Hint; + UINT8 Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA { + union { + UINT32 Function; + UINT32 Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +#endif diff --git a/sys/boot/efi/include/ia64/efibind.h b/sys/boot/efi/include/ia64/efibind.h new file mode 100644 index 0000000000..5028008251 --- /dev/null +++ b/sys/boot/efi/include/ia64/efibind.h @@ -0,0 +1,153 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/ia64/efibind.h,v 1.3 2002/05/19 03:17:22 marcel Exp $ + * $DragonFly: src/sys/boot/efi/include/ia64/efibind.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#pragma pack() + +#include + +/* Basic EFI types of various widths. */ + +typedef uint64_t UINT64; +typedef int64_t INT64; +typedef uint32_t UINT32; +typedef int32_t INT32; +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; + + +#undef VOID +#define VOID void + + +typedef int64_t INTN; +typedef uint64_t UINTN; + +/* + *XXX BugBug: Code to debug + */ +#define BIT63 0x8000000000000000 + +#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63) +#define PORT_TO_MEMD(_Port) (PLATFORM_IOBASE_ADDRESS | ( ( ( (_Port) & 0xfffc) << 10 ) | ( (_Port) & 0x0fff) ) ) + +/* Macro's with casts make this much easier to use and read. */ +#define PORT_TO_MEM8D(_Port) (*(UINT8 *)(PORT_TO_MEMD(_Port))) +#define POST_CODE(_Data) (PORT_TO_MEM8D(0x80) = (_Data)) + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while (TRUE) + +/* + * Pointers must be aligned to these address to function + * you will get an alignment fault if this value is less than 8 + */ +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value , Adjustment) \ + (UINTN) Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + +/* + * Define macros to create data structure signatures. + */ + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +/* + * To export & import functions in the EFI emulator environment + */ + +#define EXPORTAPI + +/* + * EFIAPI - prototype calling convention for EFI function pointers + * BOOTSERVICE - prototype for implementation of a boot service interface + * RUNTIMESERVICE - prototype for implementation of a runtime service interface + * RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service + * RUNTIME_CODE - pragma macro for declaring runtime code + */ + +#ifndef EFIAPI /* Forces EFI calling conventions reguardless of compiler options */ +#if _MSC_EXTENSIONS +#define EFIAPI __cdecl +#else +#define EFIAPI +#endif +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +/* + * XXX Need to find out if this is portable accross compliers. + */ +void __mf (void); +#ifndef __GNUC__ +#pragma intrinsic (__mf) +#endif +#define MEMORY_FENCE() __mf() + +/* + * When build similiar to FW, then link everything together as + * one big module. + */ + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +/* + * Some compilers don't support the forward reference construct: + * typedef struct XXXXX + * + * The following macro provide a workaround for such cases. + */ +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#ifdef __GNUC__ +#define INTERFACE_DECL(x) struct x +#else +#define INTERFACE_DECL(x) typedef struct x +#endif +#endif diff --git a/sys/boot/efi/include/ia64/pe.h b/sys/boot/efi/include/ia64/pe.h new file mode 100644 index 0000000000..44f95d87bc --- /dev/null +++ b/sys/boot/efi/include/ia64/pe.h @@ -0,0 +1,601 @@ +/* + * $FreeBSD: src/sys/boot/efi/include/ia64/pe.h,v 1.1 2001/06/09 16:49:50 dfr Exp $ + * $DragonFly: src/sys/boot/efi/include/ia64/pe.h,v 1.1 2003/11/10 06:08:32 dillon Exp $ + */ +/* + PE32+ header file + */ +#ifndef _PE_H +#define _PE_H + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + +/***************************************************************************** + * The following stuff comes from winnt.h from the ia64sdk, plus the Plabel for + * loading EM executables. + *****************************************************************************/ +// +// Intel IA64 specific +// + +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_IA64_DIR64 10 + +struct Plabel { + UINT64 EntryPoint; + UINT64 NewGP; +}; + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + UINT16 ne_magic; // Magic number + UINT8 ne_ver; // Version number + UINT8 ne_rev; // Revision number + UINT16 ne_enttab; // Offset of Entry Table + UINT16 ne_cbenttab; // Number of bytes in Entry Table + UINT32 ne_crc; // Checksum of whole file + UINT16 ne_flags; // Flag UINT16 + UINT16 ne_autodata; // Automatic data segment number + UINT16 ne_heap; // Initial heap allocation + UINT16 ne_stack; // Initial stack allocation + UINT32 ne_csip; // Initial CS:IP setting + UINT32 ne_sssp; // Initial SS:SP setting + UINT16 ne_cseg; // Count of file segments + UINT16 ne_cmod; // Entries in Module Reference Table + UINT16 ne_cbnrestab; // Size of non-resident name table + UINT16 ne_segtab; // Offset of Segment Table + UINT16 ne_rsrctab; // Offset of Resource Table + UINT16 ne_restab; // Offset of resident name table + UINT16 ne_modtab; // Offset of Module Reference Table + UINT16 ne_imptab; // Offset of Imported Names Table + UINT32 ne_nrestab; // Offset of Non-resident Names Table + UINT16 ne_cmovent; // Count of movable entries + UINT16 ne_align; // Segment alignment shift count + UINT16 ne_cres; // Count of resource segments + UINT8 ne_exetyp; // Target Operating system + UINT8 ne_flagsothers; // Other .EXE flags + UINT16 ne_pretthunks; // offset to return thunks + UINT16 ne_psegrefbytes; // offset to segment ref. bytes + UINT16 ne_swaparea; // Minimum code swap area size + UINT16 ne_expver; // Expected Windows version number + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +// +// File header format. +// + +typedef struct _IMAGE_FILE_HEADER { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +typedef struct _IMAGE_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + // UINT32 BaseOfData; + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + + +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 +#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 244 + +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS { + UINT32 Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((UINT32)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem. + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// Symbol format. +// + + +#define IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// + +#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common. +#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value. +#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item. + +// +// Type (fundamental) values. +// + +#define IMAGE_SYM_TYPE_NULL 0 // no type. +#define IMAGE_SYM_TYPE_VOID 1 // +#define IMAGE_SYM_TYPE_CHAR 2 // type character. +#define IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define IMAGE_SYM_TYPE_INT 4 // +#define IMAGE_SYM_TYPE_LONG 5 // +#define IMAGE_SYM_TYPE_FLOAT 6 // +#define IMAGE_SYM_TYPE_DOUBLE 7 // +#define IMAGE_SYM_TYPE_STRUCT 8 // +#define IMAGE_SYM_TYPE_UNION 9 // +#define IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define IMAGE_SYM_TYPE_BYTE 12 // +#define IMAGE_SYM_TYPE_WORD 13 // +#define IMAGE_SYM_TYPE_UINT 14 // +#define IMAGE_SYM_TYPE_DWORD 15 // + +// +// Type (derived) values. +// + +#define IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define IMAGE_SYM_DTYPE_POINTER 1 // pointer. +#define IMAGE_SYM_DTYPE_FUNCTION 2 // function. +#define IMAGE_SYM_DTYPE_ARRAY 3 // array. + +// +// Storage classes. +// + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +// new +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// type packing constants + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +// MACROS + +// +// Communal selection types. +// + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + + +// +// Relocation format. +// + +typedef struct _IMAGE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} IMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// + +#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +// +// MIPS relocation types. +// + +#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +// +// Alpha Relocation types. +// + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +// +// IBM PowerPC relocation types. +// + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP +#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address +#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address +#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute) +#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address +#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword) +#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative) +#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative) +#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base +#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword) + +#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base +#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr) +#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number +#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code +#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction + +#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type + +// Flag bits in IMAGE_RELOCATION.TYPE + +#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it +#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken +#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc) + +// +// Based relocation format. +// + +typedef struct _IMAGE_BASE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +// UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// +// Line number format. +// + +typedef struct _IMAGE_LINENUMBER { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} IMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; + UINT32 AddressOfNames; + UINT32 AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +typedef struct _IMAGE_IMPORT_BY_NAME { + UINT16 Hint; + UINT8 Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA { + union { + UINT32 Function; + UINT32 Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +#endif diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile new file mode 100644 index 0000000000..580e86bcd7 --- /dev/null +++ b/sys/boot/efi/libefi/Makefile @@ -0,0 +1,40 @@ +# $FreeBSD: src/sys/boot/efi/libefi/Makefile,v 1.12 2003/07/02 11:53:55 ru Exp $ +# $DragonFly: src/sys/boot/efi/libefi/Makefile,v 1.1 2003/11/10 06:08:32 dillon Exp $ + +.PATH: ${.CURDIR}/../../../${MACHINE_ARCH}/${MACHINE_ARCH} + +LIB= efi +INTERNALLIB= true + +SRCS= libefi.c efi_console.c time.c copy.c devicename.c module.c +SRCS+= delay.c efifs.c efinet.c elf_freebsd.c bootinfo.c pal.S + +.if ${MACHINE_ARCH} == "ia64" +SRCS+= efifpswa.c +.endif + +CFLAGS+= -ffreestanding -fpic +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH} +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ + +# Pick up the bootstrap header for some interface items +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. + +.if ${MACHINE_ARCH} == "powerpc" +CFLAGS+= -msoft-float +.endif + +.ifdef(BOOT_DISK_DEBUG) +# Make the disk code more talkative +CFLAGS+= -DDISK_DEBUG +.endif + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +CLEANFILES+= machine + +.include + +beforedepend ${OBJS}: machine diff --git a/sys/boot/efi/libefi/arch/ia64/ldscript.ia64 b/sys/boot/efi/libefi/arch/ia64/ldscript.ia64 new file mode 100644 index 0000000000..a3300edb0f --- /dev/null +++ b/sys/boot/efi/libefi/arch/ia64/ldscript.ia64 @@ -0,0 +1,76 @@ +/* + * $FreeBSD: src/sys/boot/efi/libefi/arch/ia64/ldscript.ia64,v 1.7 2003/07/17 00:32:08 marcel Exp $ + * $DragonFly: src/sys/boot/efi/libefi/arch/ia64/ldscript.ia64,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ +OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little", "elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(_start_plabel) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + ImageBase = .; + . = SIZEOF_HEADERS; + . = ALIGN(4096); + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0x00300000010070000002000001000400 + . = ALIGN(4096); + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) + *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) + __start_set_Xcommand_set = .; + *(set_Xcommand_set) + __stop_set_Xcommand_set = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } + . = ALIGN(4096); + __gp = .; + .sdata : { + *(.got.plt .got) + *(.IA_64.pltoff) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela : { + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.plt) + *(.rela.IA_64.pltoff) + *(.relaset_*) + *(.rela.dyn .rela.dyn.*) + } + . = ALIGN(4096); + .reloc : { *(.reloc) } + . = ALIGN(4096); + .hash : { *(.hash) } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } +} diff --git a/sys/boot/efi/libefi/arch/ia64/start.S b/sys/boot/efi/libefi/arch/ia64/start.S new file mode 100644 index 0000000000..7f847ac2a3 --- /dev/null +++ b/sys/boot/efi/libefi/arch/ia64/start.S @@ -0,0 +1,306 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/boot/efi/libefi/arch/ia64/start.S,v 1.6 2002/12/10 04:14:01 marcel Exp $ + * $DragonFly: src/sys/boot/efi/libefi/arch/ia64/start.S,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + + .text + +#include + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR 1 +#define EFI_BUFFER_TOO_SMALL 5 + +#define DT_NULL 0 /* Terminating entry. */ +#define DT_NEEDED 1 /* String table offset of a needed shared + library. */ +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +#define DT_SONAME 14 /* String table offset of shared object + name. */ +#define DT_RPATH 15 /* String table offset of library path. */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +#define DT_TEXTREL 22 /* Indicates there may be relocations in + non-writable segments. */ +#define DT_JMPREL 23 /* Address of PLT relocations. */ + +#define DT_COUNT 24 /* Number of defined d_tag values. */ + +#define R_IA64_NONE 0 /* None */ +#define R_IA64_DIR64MSB 0x26 /* word64 MSB S + A */ +#define R_IA64_DIR64LSB 0x27 /* word64 LSB S + A */ +#define R_IA64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ +#define R_IA64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ +#define R_IA64_REL64MSB 0x6e /* word64 MSB BD + A */ +#define R_IA64_REL64LSB 0x6f /* word64 LSB BD + A */ +#define R_IA64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ + +ENTRY(_start, 2) + alloc loc0=ar.pfs,2,3,3,0 + mov loc1=rp + movl loc2=@gprel(ImageBase) + ;; + add loc2=gp,loc2 + ;; + mov out0=loc2 + mov out1=in1 + ;; + br.call.sptk.few rp=_reloc // relocate image + + cmp.ne p6,p0=EFI_SUCCESS,r8 // did it work? +(p6) br.cond.dpnt.few 9f + + mov out0=in0 // image_handle + mov out1=in1 // system_table + br.call.sptk.few rp=efi_main +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp +END(_start) + + // PLABEL for PE32+ + .global _start_plabel + .section .plabel, "a" + .align 16 +_start_plabel: + .quad _start + .quad __gp + .previous + + // A PE32+ relocation entry for the plabel + + .section .reloc, "a" + .long _start_plabel + .long 12 + .short (10 << 12) + 0 + .short (10 << 12) + 8 + .previous + +// in0: image base +// in1: system table +// +// XXX Assumes PLT relocations are of type Elf_Rela +// +// r2 = address of fptr_storage +// r3 = address of fptr_storage_end +// r4 = address of first free fptr +// +// r15 = r_offset +// r16 = r_info -OR- d_tag +// r17 = r_addend -OR- d_val (=d_ptr) +// r18 = address of .rela dynamic section +// r19 = size of .rela section +// r20 = size of .rela element (Elf_Rela) +// r21 = address of first PLT relocation +// r22 = size of PLT relocations +// r23 = relocation type +// r24 = address of symbol +// r28 = R_IA64_IPLTLSB +// f8 = address of symbol table +// f9 = size of symtab element + +STATIC_ENTRY(_reloc, 2) + alloc loc0=ar.pfs,2,2,0,0 + ;; + mov loc1=rp + movl r29=@gprel(_DYNAMIC) // find _DYNAMIC etc. + ;; + add r15=r29,gp + movl r29=@gprel(fptr_storage) + ;; + add r2=r29,gp + movl r29=@gprel(fptr_storage_end) + ;; + add r3=r29,gp + mov r4=r2 + mov r19=0 + mov r22=0 + mov r20=24 + mov r28=R_IA64_IPLTLSB + ;; +1: + ld8 r16=[r15],8 // read r15->d_tag + ;; + ld8 r17=[r15],8 // and r15->d_val + ;; + cmp.eq p6,p0=DT_NULL,r16 // done? +(p6) br.cond.dpnt.few 2f + ;; + cmp.eq p6,p0=DT_RELA,r16 // rela section? + ;; +(p6) add r18=r17,in0 + cmp.eq p6,p0=DT_RELASZ,r16 // rela section size? + ;; +(p6) mov r19=r17 + cmp.eq p6,p0=DT_RELAENT,r16 // rela entry size? + ;; +(p6) mov r20=r17 + cmp.eq p6,p0=DT_JMPREL,r16 // PLT relocs? + ;; +(p6) add r21=r17,in0 + cmp.eq p6,p0=DT_PLTRELSZ,r16 // PLT relocs size? + ;; +(p6) mov r22=r17 + cmp.eq p6,p0=DT_SYMTAB,r16 // symbol table? + ;; +(p6) add r29=r17,in0 + ;; +(p6) setf.sig f8=r29 + cmp.eq p6,p0=DT_SYMENT,r16 // symbol entry size? + ;; +(p6) setf.sig f9=r17 + br.dptk 1b + +2: + cmp.lt p6,p0=0,r19 +(p6) br.cond.dptk 3f + ;; + mov r19=r22 + mov r18=r21 + mov r21=0 + mov r22=0 + ;; + cmp.lt p6,p0=0,r19 +(p6) br.cond.dptk 3f + ;; + mov r8=EFI_SUCCESS + br.dptk 9f +3: + ld8 r29=[r18],8 // read r_offset + ;; + ld8 r16=[r18],8 // read r_info + add r15=r29,in0 // relocate r_offset + ;; + ld8 r17=[r18],8 // read r_addend + sub r19=r19,r20 // update relasz + extr.u r23=r16,0,32 // ELF64_R_TYPE(r16) + ;; + cmp.eq p6,p0=R_IA64_NONE,r23 +(p6) br.cond.dpnt.few 2b + ;; + cmp.eq p6,p0=R_IA64_REL64LSB,r23 +(p6) br.cond.dptk.few 4f + ;; + extr.u r29=r16,32,32 // ELF64_R_SYM(r16) + ;; + setf.sig f10=r29 // so we can multiply + ;; + xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment + ;; + getf.sig r29=f10 + ;; + add r29=8,r29 // address of st_value + ;; + ld8 r29=[r29] // read symbol value + ;; + add r24=r29,in0 // relocate symbol value + ;; + cmp.eq p6,p0=R_IA64_DIR64LSB,r23 +(p6) br.cond.dptk.few 5f + ;; + cmp.eq p6,p0=R_IA64_FPTR64LSB,r23 +(p6) br.cond.dptk.few 6f + ;; + cmp.ne p6,p0=r28,r23 // IPLTLSB +(p6) br.cond.dptk.few 2b + + // IPLTLSB + add r29=r24,r17 // S + A + ;; + st8 [r15]=r29,8 // fdesc:FP + ;; + st8 [r15]=gp // fdesc:GP + br.cond.sptk.few 2b + + // REL64LSB +4: + add r29=in0,r17 // BD + A + ;; + st8 [r15]=r29 // word64 + br.cond.sptk.few 2b + + // DIR64LSB +5: + add r29=r24,r17 // S + A + ;; + st8 [r15]=r29 // word64 + br.cond.sptk.few 2b + +6: + mov r29=r2 // FPTR64LSB + ;; +7: + cmp.geu p6,p0=r29,r4 // end of fptrs? +(p6) br.cond.dpnt.few 8f // can't find existing fptr + ld8 r17=[r29] // read function from fptr + ;; + cmp.eq p6,p0=r24,r17 // same function? + ;; +(p6) st8 [r15]=r29 // reuse fptr +(p6) br.cond.sptk.few 2b // done + add r29=16,r29 // next fptr + br.sptk.few 7b +8: + mov r8=EFI_BUFFER_TOO_SMALL // failure return value + cmp.geu p6,p0=r4,r3 // space left? +(p6) br.cond.dpnt.few 9f // bail out + st8 [r15]=r4 // install fptr + ;; + st8 [r4]=r24,8 // write fptr address + ;; + st8 [r4]=gp,8 // write fptr gp + br.cond.sptk.few 2b + +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp +END(_reloc) + + .data + .align 16 +fptr_storage: + .space 1024*16 // XXX +fptr_storage_end: diff --git a/sys/boot/pc32/libi386/bootinfo.c b/sys/boot/efi/libefi/bootinfo.c similarity index 60% copy from sys/boot/pc32/libi386/bootinfo.c copy to sys/boot/efi/libefi/bootinfo.c index fd0a93daa6..a1ea248e88 100644 --- a/sys/boot/pc32/libi386/bootinfo.c +++ b/sys/boot/efi/libefi/bootinfo.c @@ -23,20 +23,24 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/i386/libi386/bootinfo.c,v 1.23.2.6 2002/01/07 07:37:52 jhb Exp $ - * $DragonFly: src/sys/boot/pc32/libi386/bootinfo.c,v 1.2 2003/06/17 04:28:18 dillon Exp $ + * $FreeBSD$ + * $DragonFly: src/sys/boot/efi/libefi/bootinfo.c,v 1.1 2003/11/10 06:08:32 dillon Exp $ */ #include +#include #include #include #include +#include #include + +#include +#include + #include "bootstrap.h" -#include "libi386.h" -#include "btxv86.h" -static struct bootinfo bi; +static EFI_GUID hcdp = HCDP_TABLE_GUID; /* * Return a 'boothowto' value corresponding to the kernel arguments in @@ -54,10 +58,12 @@ static struct {"boot_gdb", RB_GDB}, {"boot_single", RB_SINGLE}, {"boot_verbose", RB_VERBOSE}, + {"boot_multicons", RB_MULTIPLE}, + {"boot_serial", RB_SERIAL}, {NULL, 0} }; -vm_offset_t bi_copymodules(vm_offset_t addr); +extern char *efi_fmtdev(void *vdev); int bi_getboothowto(char *kargs) @@ -89,6 +95,9 @@ bi_getboothowto(char *kargs) case 'd': howto |= RB_KDB; break; + case 'D': + howto |= RB_MULTIPLE; + break; case 'm': howto |= RB_MUTE; break; @@ -98,9 +107,6 @@ bi_getboothowto(char *kargs) case 'h': howto |= RB_SERIAL; break; - case 'p': - howto |= RB_PAUSE; - break; case 'r': howto |= RB_DFLTROOT; break; @@ -140,18 +146,18 @@ bi_copyenv(vm_offset_t addr) /* traverse the environment */ for (ep = environ; ep != NULL; ep = ep->ev_next) { - i386_copyin(ep->ev_name, addr, strlen(ep->ev_name)); + efi_copyin(ep->ev_name, addr, strlen(ep->ev_name)); addr += strlen(ep->ev_name); - i386_copyin("=", addr, 1); + efi_copyin("=", addr, 1); addr++; if (ep->ev_value != NULL) { - i386_copyin(ep->ev_value, addr, strlen(ep->ev_value)); + efi_copyin(ep->ev_value, addr, strlen(ep->ev_value)); addr += strlen(ep->ev_value); } - i386_copyin("", addr, 1); + efi_copyin("", addr, 1); addr++; } - i386_copyin("", addr, 1); + efi_copyin("", addr, 1); addr++; return(addr); } @@ -161,7 +167,7 @@ bi_copyenv(vm_offset_t addr) * used as a directory for loaded modules. * * Module data is presented in a self-describing format. Each datum - * is preceeded by a 32-bit identifier and a 32-bit size field. + * is preceded by a 32-bit identifier and a 32-bit size field. * * Currently, the following data are saved: * @@ -174,15 +180,15 @@ bi_copyenv(vm_offset_t addr) */ #define COPY32(v, a) { \ u_int32_t x = (v); \ - i386_copyin(&x, a, sizeof(x)); \ + efi_copyin(&x, a, sizeof(x)); \ a += sizeof(x); \ } #define MOD_STR(t, a, s) { \ COPY32(t, a); \ COPY32(strlen(s) + 1, a); \ - i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_long));\ + efi_copyin(s, a, strlen(s) + 1); \ + a += roundup(strlen(s) + 1, sizeof(u_int64_t));\ } #define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) @@ -192,8 +198,8 @@ bi_copyenv(vm_offset_t addr) #define MOD_VAR(t, a, s) { \ COPY32(t, a); \ COPY32(sizeof(s), a); \ - i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ + efi_copyin(&s, a, sizeof(s)); \ + a += roundup(sizeof(s), sizeof(u_int64_t)); \ } #define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) @@ -202,8 +208,8 @@ bi_copyenv(vm_offset_t addr) #define MOD_METADATA(a, mm) { \ COPY32(MODINFO_METADATA | mm->md_type, a); \ COPY32(mm->md_size, a); \ - i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_long));\ + efi_copyin(mm->md_data, a, mm->md_size); \ + a += roundup(mm->md_size, sizeof(u_int64_t));\ } #define MOD_END(a) { \ @@ -214,19 +220,19 @@ bi_copyenv(vm_offset_t addr) vm_offset_t bi_copymodules(vm_offset_t addr) { - struct loaded_module *mp; - struct module_metadata *md; + struct preloaded_file *fp; + struct file_metadata *md; /* start with the first module on the list, should be the kernel */ - for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) { - - MOD_NAME(addr, mp->m_name); /* this field must come first */ - MOD_TYPE(addr, mp->m_type); - if (mp->m_args) - MOD_ARGS(addr, mp->m_args); - MOD_ADDR(addr, mp->m_addr); - MOD_SIZE(addr, mp->m_size); - for (md = mp->m_metadata; md != NULL; md = md->md_next) + for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { + + MOD_NAME(addr, fp->f_name); /* this field must come first */ + MOD_TYPE(addr, fp->f_type); + if (fp->f_args) + MOD_ARGS(addr, fp->f_args); + MOD_ADDR(addr, fp->f_addr); + MOD_SIZE(addr, fp->f_size); + for (md = fp->f_metadata; md != NULL; md = md->md_next) if (!(md->md_type & MODINFOMD_NOCOPY)) MOD_METADATA(addr, md); } @@ -235,125 +241,109 @@ bi_copymodules(vm_offset_t addr) } /* - * Load the information expected by an i386 kernel. + * Load the information expected by an alpha kernel. * - * - The 'boothowto' argument is constructed - * - The 'bootdev' argument is constructed - * - The 'bootinfo' struct is constructed, and copied into the kernel space. * - The kernel environment is copied into kernel space. * - Module metadata are formatted and placed in kernel space. */ int -bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) +bi_load(struct bootinfo *bi, struct preloaded_file *fp, UINTN *mapkey, + UINTN pages) { - struct loaded_module *xp; - struct i386_devdesc *rootdev; - vm_offset_t addr; char *rootdevname; - int bootdevnr, i; - u_int pad; - char *kernelname; - const char *kernelpath; + struct efi_devdesc *rootdev; + struct preloaded_file *xp; + vm_offset_t addr, bootinfo_addr; + vm_offset_t ssym, esym; + struct file_metadata *md; + EFI_STATUS status; + UINTN bisz, key; + + /* + * Version 1 bootinfo. + */ + bi->bi_magic = BOOTINFO_MAGIC; + bi->bi_version = 1; + + /* + * Calculate boothowto. + */ + bi->bi_boothowto = bi_getboothowto(fp->f_args); - *howtop = bi_getboothowto(args); + /* + * Stash EFI System Table. + */ + bi->bi_systab = (u_int64_t) ST; /* - * Allow the environment variable 'rootdev' to override the supplied device - * This should perhaps go to MI code and/or have $rootdev tested/set by - * MI code before launching the kernel. + * Allow the environment variable 'rootdev' to override the supplied + * device. This should perhaps go to MI code and/or have $rootdev + * tested/set by MI code before launching the kernel. */ rootdevname = getenv("rootdev"); - i386_getdev((void **)(&rootdev), rootdevname, NULL); + efi_getdev((void **)(&rootdev), rootdevname, NULL); if (rootdev == NULL) { /* bad $rootdev/$currdev */ printf("can't determine root device\n"); return(EINVAL); } /* Try reading the /etc/fstab file to select the root device */ - getrootmount(i386_fmtdev((void *)rootdev)); - - /* Do legacy rootdev guessing */ - - /* XXX - use a default bootdev of 0. Is this ok??? */ - bootdevnr = 0; - - switch(rootdev->d_type) { - case DEVT_CD: - /* Pass in BIOS device number. */ - bi.bi_bios_dev = bc_unit2bios(rootdev->d_kind.bioscd.unit); - bootdevnr = bc_getdev(rootdev); - break; - - case DEVT_DISK: - /* pass in the BIOS device number of the current disk */ - bi.bi_bios_dev = bd_unit2bios(rootdev->d_kind.biosdisk.unit); - bootdevnr = bd_getdev(rootdev); - break; - - case DEVT_NET: - break; - - default: - printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type); - } - if (bootdevnr == -1) { - printf("root device %s invalid\n", i386_fmtdev(rootdev)); - return (EINVAL); - } + getrootmount(efi_fmtdev((void *)rootdev)); free(rootdev); - *bootdevp = bootdevnr; - - /* legacy bootinfo structure */ - bi.bi_version = BOOTINFO_VERSION; - bi.bi_kernelname = 0; /* XXX char * -> kernel name */ - bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */ - bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */ - for (i = 0; i < N_BIOS_GEOM; i++) - bi.bi_bios_geom[i] = bd_getbigeom(i); - bi.bi_size = sizeof(bi); - bi.bi_memsizes_valid = 1; - bi.bi_basemem = bios_basemem / 1024; - bi.bi_extmem = bios_extmem / 1024; + + ssym = esym = 0; + if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL) + ssym = *((vm_offset_t *)&(md->md_data)); + if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL) + esym = *((vm_offset_t *)&(md->md_data)); + if (ssym == 0 || esym == 0) + ssym = esym = 0; /* sanity */ + + bi->bi_symtab = ssym; + bi->bi_esymtab = esym; + + bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp); /* DIG64 HCDP table addr. */ + fpswa_init(&bi->bi_fpswa); /* find FPSWA interface */ /* find the last module in the chain */ addr = 0; - for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) { - if (addr < (xp->m_addr + xp->m_size)) - addr = xp->m_addr + xp->m_size; + for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { + if (addr < (xp->f_addr + xp->f_size)) + addr = xp->f_addr + xp->f_size; } + /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } + addr = (addr + PAGE_MASK) & ~PAGE_MASK; /* copy our environment */ - bi.bi_envp = addr; + bi->bi_envp = addr; addr = bi_copyenv(addr); /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + /* copy module list and metadata */ - bi.bi_modulep = addr; + bi->bi_modulep = addr; addr = bi_copymodules(addr); /* all done copying stuff in, save end of loaded object space */ - bi.bi_kernend = addr; - - *howtop |= RB_BOOTINFO; /* it's there now */ + bi->bi_kernend = addr; /* - * Get the kernel name, strip off any device prefix. + * Read the memory map and stash it after bootinfo. Align the memory map + * on a 16-byte boundary (the bootinfo block is page aligned). */ - kernelname = getenv("kernelname"); - i386_getdev(NULL, kernelname, &kernelpath); - bi.bi_kernelname = VTOP(kernelpath); - *bip = VTOP(&bi); + bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f; + bi->bi_memmap = ((u_int64_t)bi) + bisz; + bi->bi_memmap_size = EFI_PAGE_SIZE * pages - bisz; + status = BS->GetMemoryMap(&bi->bi_memmap_size, + (EFI_MEMORY_DESCRIPTOR *)bi->bi_memmap, &key, + &bi->bi_memdesc_size, &bi->bi_memdesc_version); + if (EFI_ERROR(status)) { + printf("bi_load: Can't read memory map\n"); + return EINVAL; + } + *mapkey = key; return(0); } diff --git a/sys/boot/alpha/libalpha/alpha_copy.c b/sys/boot/efi/libefi/copy.c similarity index 65% copy from sys/boot/alpha/libalpha/alpha_copy.c copy to sys/boot/efi/libefi/copy.c index 54b952e058..fd8a0aa47e 100644 --- a/sys/boot/alpha/libalpha/alpha_copy.c +++ b/sys/boot/efi/libefi/copy.c @@ -23,36 +23,45 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/alpha/libalpha/alpha_copy.c,v 1.4.2.1 2000/12/28 13:12:24 ps Exp $ - * $DragonFly: src/sys/boot/alpha/libalpha/Attic/alpha_copy.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/efi/libefi/copy.c,v 1.1 2003/11/10 06:08:32 dillon Exp $ */ + /* * MD primitives supporting placement of module data - * - * XXX should check load address/size against memory top. */ #include -#include "libalpha.h" +#include +#include +#include +#include -ssize_t -alpha_copyin(const void *src, vm_offset_t dest, const size_t len) +int +efi_copyin(void *src, vm_offset_t dest, size_t len) { - bcopy(src, (void *)dest, len); - return(len); + EFI_PHYSICAL_ADDRESS p = IA64_RR_MASK(dest); +#if 0 + BS->AllocatePages(AllocateAddress, EfiRuntimeServicesData, + len >> 12, &p); +#endif + bcopy(src, (void*) p, len); + return (len); } -ssize_t -alpha_copyout(const vm_offset_t src, void *dest, const size_t len) +int +efi_copyout(vm_offset_t src, void *dest, size_t len) { - bcopy((void *)src, dest, len); - return(len); + bcopy((void*) IA64_RR_MASK(src), dest, len); + return (len); } -ssize_t -alpha_readin(const int fd, vm_offset_t dest, const size_t len) +int +efi_readin(int fd, vm_offset_t dest, size_t len) { - return(read(fd, (void *) dest, len)); + EFI_PHYSICAL_ADDRESS p = IA64_RR_MASK(dest); +#if 0 + BS->AllocatePages(AllocateAddress, EfiRuntimeServicesData, + len >> 12, &p); +#endif + return (read(fd, (void*) p, len)); } - - diff --git a/sys/boot/arc/lib/delay.c b/sys/boot/efi/libefi/delay.c similarity index 77% copy from sys/boot/arc/lib/delay.c copy to sys/boot/efi/libefi/delay.c index 7e4b229072..5bcedb59d2 100644 --- a/sys/boot/arc/lib/delay.c +++ b/sys/boot/efi/libefi/delay.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998 Doug Rabson + * Copyright (c) 2001 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,17 +23,24 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/arc/lib/delay.c,v 1.2 1999/08/28 00:39:37 peter Exp $ - * $DragonFly: src/sys/boot/arc/lib/Attic/delay.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/efi/libefi/delay.c,v 1.1 2003/11/10 06:08:32 dillon Exp $ */ -#include -#include -#include "arctypes.h" -#include "arcfuncs.h" +#include +#include void delay(int usecs) { - StallExecution(usecs); + static EFI_EVENT ev = 0; + UINTN junk; + + if (!ev) { + if (BS->CreateEvent(EVT_TIMER, TPL_APPLICATION, 0, 0, &ev) + != EFI_SUCCESS) + return; + } + + BS->SetTimer(ev, TimerRelative, usecs * 10); + BS->WaitForEvent(1, &ev, &junk); } diff --git a/sys/boot/efi/libefi/devicename.c b/sys/boot/efi/libefi/devicename.c new file mode 100644 index 0000000000..7833282185 --- /dev/null +++ b/sys/boot/efi/libefi/devicename.c @@ -0,0 +1,241 @@ +/*- + * Copyright (c) 1998 Michael Smith + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/boot/efi/libefi/devicename.c,v 1.2 2001/09/07 08:49:47 dfr Exp $ + * $DragonFly: src/sys/boot/efi/libefi/devicename.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include +#include "bootstrap.h" + +#include +#include +#include "efiboot.h" + +static int efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path); + +/* + * Point (dev) at an allocated device specifier for the device matching the + * path in (devspec). If it contains an explicit device specification, + * use that. If not, use the default device. + */ +int +efi_getdev(void **vdev, const char *devspec, const char **path) +{ + struct efi_devdesc **dev = (struct efi_devdesc **)vdev; + int rv; + + /* + * If it looks like this is just a path and no + * device, go with the current device. + */ + if ((devspec == NULL) || + (devspec[0] == '/') || + (strchr(devspec, ':') == NULL)) { + + if (((rv = efi_parsedev(dev, getenv("currdev"), NULL)) == 0) && + (path != NULL)) + *path = devspec; + return(rv); + } + + /* + * Try to parse the device name off the beginning of the devspec + */ + return(efi_parsedev(dev, devspec, path)); +} + +/* + * Point (dev) at an allocated device specifier matching the string version + * at the beginning of (devspec). Return a pointer to the remaining + * text in (path). + * + * In all cases, the beginning of (devspec) is compared to the names + * of known devices in the device switch, and then any following text + * is parsed according to the rules applied to the device type. + * + * For disk-type devices, the syntax is: + * + * disk[s][]: + * + */ +static int +efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path) +{ + struct efi_devdesc *idev; + struct devsw *dv; + int i, unit, slice, partition, err; + char *cp; + const char *np; + + /* minimum length check */ + if (strlen(devspec) < 2) + return(EINVAL); + + /* look for a device that matches */ + for (i = 0, dv = NULL; devsw[i] != NULL; i++) { + if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) { + dv = devsw[i]; + break; + } + } + + if (dv == NULL) + return(ENOENT); + idev = malloc(sizeof(struct efi_devdesc)); + err = 0; + np = (devspec + strlen(dv->dv_name)); + + switch(dv->dv_type) { + case DEVT_NONE: /* XXX what to do here? Do we care? */ + break; + + case DEVT_DISK: + unit = -1; + slice = -1; + partition = -1; + if (*np && (*np != ':')) { + unit = strtol(np, &cp, 10); /* next comes the unit number */ + if (cp == np) { + err = EUNIT; + goto fail; + } + if (*cp == 's') { /* got a slice number */ + np = cp + 1; + slice = strtol(np, &cp, 10); + if (cp == np) { + err = ESLICE; + goto fail; + } + } + if (*cp && (*cp != ':')) { + partition = *cp - 'a'; /* get a partition number */ + if ((partition < 0) || (partition >= MAXPARTITIONS)) { + err = EPART; + goto fail; + } + cp++; + } + } + if (*cp && (*cp != ':')) { + err = EINVAL; + goto fail; + } + + idev->d_kind.efidisk.unit = unit; + idev->d_kind.efidisk.slice = slice; + idev->d_kind.efidisk.partition = partition; + + if (path != NULL) + *path = (*cp == 0) ? cp : cp + 1; + break; + + case DEVT_NET: + unit = 0; + + if (*np && (*np != ':')) { + unit = strtol(np, &cp, 0); /* get unit number if present */ + if (cp == np) { + err = EUNIT; + goto fail; + } + } + if (*cp && (*cp != ':')) { + err = EINVAL; + goto fail; + } + + idev->d_kind.netif.unit = unit; + if (path != NULL) + *path = (*cp == 0) ? cp : cp + 1; + break; + + default: + err = EINVAL; + goto fail; + } + idev->d_dev = dv; + idev->d_type = dv->dv_type; + if (dev == NULL) { + free(idev); + } else { + *dev = idev; + } + return(0); + + fail: + free(idev); + return(err); +} + + +char * +efi_fmtdev(void *vdev) +{ + struct efi_devdesc *dev = (struct efi_devdesc *)vdev; + static char buf[128]; /* XXX device length constant? */ + char *cp; + + switch(dev->d_type) { + case DEVT_NONE: + strcpy(buf, "(no device)"); + break; + + case DEVT_DISK: + cp = buf; + cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_kind.efidisk.unit); + if (dev->d_kind.efidisk.slice > 0) + cp += sprintf(cp, "s%d", dev->d_kind.efidisk.slice); + if (dev->d_kind.efidisk.partition >= 0) + cp += sprintf(cp, "%c", dev->d_kind.efidisk.partition + 'a'); + strcat(cp, ":"); + break; + + case DEVT_NET: + sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_kind.netif.unit); + break; + } + return(buf); +} + + +/* + * Set currdev to suit the value being supplied in (value) + */ +int +efi_setcurrdev(struct env_var *ev, int flags, void *value) +{ + struct efi_devdesc *ncurr; + int rv; + + if ((rv = efi_parsedev(&ncurr, value, NULL)) != 0) + return(rv); + free(ncurr); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + return(0); +} + diff --git a/sys/boot/common/devopen.c b/sys/boot/efi/libefi/efi_console.c similarity index 53% copy from sys/boot/common/devopen.c copy to sys/boot/efi/libefi/efi_console.c index 349034719f..4f5b105582 100644 --- a/sys/boot/common/devopen.c +++ b/sys/boot/efi/libefi/efi_console.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998 Michael Smith + * Copyright (c) 2000 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,40 +23,75 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/devopen.c,v 1.3 1999/08/28 00:39:47 peter Exp $ - * $DragonFly: src/sys/boot/common/devopen.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/efi/libefi/efi_console.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ */ - -#include -#include +#include +#include #include "bootstrap.h" +static SIMPLE_TEXT_OUTPUT_INTERFACE *conout; +static SIMPLE_INPUT_INTERFACE *conin; + +static void +efi_cons_probe(struct console *cp) +{ + conout = ST->ConOut; + conin = ST->ConIn; + cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; +} + +static int +efi_cons_init(int arg) +{ + return 0; +} + +void +efi_cons_putchar(int c) +{ + CHAR16 buf[2]; + + if (c == '\n') + efi_cons_putchar('\r'); + + buf[0] = c; + buf[1] = 0; + + conout->OutputString(conout, buf); +} + int -devopen(struct open_file *f, const char *fname, const char **file) +efi_cons_getchar() { - struct devdesc *dev; - int result; - - if ((result = archsw.arch_getdev((void *)&dev, fname, file)) == 0) { /* get the device */ - /* point to device-specific data so that device open can use it */ - f->f_devdata = dev; - if ((result = dev->d_dev->dv_open(f, dev)) == 0) { /* try to open it */ - /* reference the devsw entry from the open_file structure */ - f->f_dev = dev->d_dev; - } else { - free(dev); /* release the device descriptor */ + EFI_INPUT_KEY key; + EFI_STATUS status; + UINTN junk; + + /* Try to read a key stroke. We wait for one if none is pending. */ + status = conin->ReadKeyStroke(conin, &key); + if (status == EFI_NOT_READY) { + BS->WaitForEvent(1, &conin->WaitForKey, &junk); + status = conin->ReadKeyStroke(conin, &key); } - } - return(result); + return (key.UnicodeChar); } int -devclose(struct open_file *f) +efi_cons_poll() { - if (f->f_devdata != NULL) { - free(f->f_devdata); - } - return(0); + /* This can clear the signaled state. */ + return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS); } + +struct console efi_console = { + "efi", + "EFI console", + 0, + efi_cons_probe, + efi_cons_init, + efi_cons_putchar, + efi_cons_getchar, + efi_cons_poll +}; diff --git a/sys/boot/alpha/libalpha/libalpha.h b/sys/boot/efi/libefi/efiboot.h similarity index 55% copy from sys/boot/alpha/libalpha/libalpha.h copy to sys/boot/efi/libefi/efiboot.h index 6072139cc0..4ef4de02a0 100644 --- a/sys/boot/alpha/libalpha/libalpha.h +++ b/sys/boot/efi/libefi/efiboot.h @@ -1,6 +1,3 @@ -/* $FreeBSD: src/sys/boot/alpha/libalpha/libalpha.h,v 1.5.2.1 2000/12/28 13:12:24 ps Exp $ */ -/* $DragonFly: src/sys/boot/alpha/libalpha/Attic/libalpha.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ - /* * Copyright (c) 1996 * Matthias Drochner. All rights reserved. @@ -31,53 +28,68 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * $FreeBSD: src/sys/boot/efi/libefi/efiboot.h,v 1.8 2003/08/02 08:22:03 marcel Exp $ + * $DragonFly: src/sys/boot/efi/libefi/efiboot.h,v 1.1 2003/11/10 06:08:33 dillon Exp $ */ - /* - * alpha fully-qualified device descriptor + * EFI fully-qualified device descriptor */ -struct alpha_devdesc -{ - struct devsw *d_dev; - int d_type; -#define DEVT_NONE 0 -#define DEVT_DISK 1 -#define DEVT_NET 2 - union - { - struct - { - int unit; - int slice; - int partition; - } srmdisk; - struct - { - int unit; /* XXX net layer lives over these? */ - } netif; - } d_kind; +struct efi_devdesc { + struct devsw *d_dev; + int d_type; +#define DEVT_NONE 0 +#define DEVT_DISK 1 +#define DEVT_NET 2 + EFI_HANDLE d_handle; + union { + struct { + int unit; + int slice; + int partition; + } efidisk; + struct { + int unit; /* XXX net layer lives over these? */ + } netif; + } d_kind; }; -extern int alpha_getdev(void **vdev, const char *devspec, const char **path); -extern char *alpha_fmtdev(void *vdev); -extern int alpha_setcurrdev(struct env_var *ev, int flags, void *value); +extern int efi_getdev(void **vdev, const char *devspec, const char **path); +extern char *efi_fmtdev(void *vdev); +extern int efi_setcurrdev(struct env_var *ev, int flags, void *value); -#define MAXDEV 31 /* maximum number of distinct devices */ +#define MAXDEV 31 /* maximum number of distinct devices */ typedef unsigned long physaddr_t; /* exported devices XXX rename? */ -extern struct devsw srmdisk; -extern struct netif_driver srmnet; +extern struct devsw efifs_dev; +extern struct devsw efi_disk; +extern struct netif_driver efi_net; + +/* Find EFI network resources */ +extern void efinet_init_driver(void); + +/* Map handles to units */ +int efifs_get_unit(EFI_HANDLE); + +/* Wrapper over EFI filesystems. */ +extern struct fs_ops efi_fsops; /* this is in startup code */ extern void delay(int); extern void reboot(void); -ssize_t alpha_copyin(const void *src, vm_offset_t dest, const size_t len); -ssize_t alpha_copyout(const vm_offset_t src, void *dest, const size_t len); -ssize_t alpha_readin(const int fd, vm_offset_t dest, const size_t len); +extern ssize_t efi_copyin(const void *src, vm_offset_t dest, size_t len); +extern ssize_t efi_copyout(const vm_offset_t src, void *dest, size_t len); +extern ssize_t efi_readin(int fd, vm_offset_t dest, size_t len); + +extern int efi_boot(void); +extern int efi_autoload(void); + +extern int fpswa_init(u_int64_t *fpswa_interface); -extern int alpha_boot(void); -extern int alpha_autoload(void); +struct bootinfo; +struct preloaded_file; +extern int bi_load(struct bootinfo *, struct preloaded_file *, + UINTN *mapkey, UINTN pages); diff --git a/sys/boot/pc32/libi386/i386_module.c b/sys/boot/efi/libefi/efifpswa.c similarity index 61% copy from sys/boot/pc32/libi386/i386_module.c copy to sys/boot/efi/libefi/efifpswa.c index b0bdc8a38e..2af215eccf 100644 --- a/sys/boot/pc32/libi386/i386_module.c +++ b/sys/boot/efi/libefi/efifpswa.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998 Michael Smith + * Copyright (c) 2001 Peter Wemm * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,27 +23,38 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/i386/libi386/i386_module.c,v 1.3 1999/08/28 00:40:15 peter Exp $ - * $DragonFly: src/sys/boot/pc32/libi386/i386_module.c,v 1.2 2003/06/17 04:28:18 dillon Exp $ - */ - -/* - * i386-specific module functionality. - * + * $FreeBSD: src/sys/boot/efi/libefi/efifpswa.c,v 1.1 2001/11/19 07:09:47 peter Exp $ + * $DragonFly: src/sys/boot/efi/libefi/efifpswa.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ */ +#include +#include +#include #include -#include +#include -#include "bootstrap.h" -#include "libi386.h" +#include +#include +#include "efiboot.h" -/* - * Use voodoo to load modules required by current hardware. - */ int -i386_autoload(void) +fpswa_init(u_int64_t *fpswa_interface) { - /* XXX use PnP to locate stuff here */ - return(0); + EFI_STATUS status; + static EFI_GUID fpswaid = EFI_INTEL_FPSWA; + UINTN sz; + EFI_HANDLE fpswa_handle; + FPSWA_INTERFACE *fpswa; + + *fpswa_interface = 0; + sz = sizeof(EFI_HANDLE); + status = BS->LocateHandle(ByProtocol, &fpswaid, 0, &sz, &fpswa_handle); + if (EFI_ERROR(status)) + return ENOENT; + + status = BS->HandleProtocol(fpswa_handle, &fpswaid, (VOID **)&fpswa); + if (EFI_ERROR(status)) + return ENOENT; + *fpswa_interface = (u_int64_t)fpswa; + return 0; } diff --git a/sys/boot/efi/libefi/efifs.c b/sys/boot/efi/libefi/efifs.c new file mode 100644 index 0000000000..08f1729416 --- /dev/null +++ b/sys/boot/efi/libefi/efifs.c @@ -0,0 +1,402 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/boot/efi/libefi/efifs.c,v 1.8 2003/08/02 08:22:03 marcel Exp $ + * $DragonFly: src/sys/boot/efi/libefi/efifs.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "efiboot.h" + +/* Perform I/O in blocks of size EFI_BLOCK_SIZE. */ +#define EFI_BLOCK_SIZE (1024 * 1024) + +static int +efifs_open(const char *upath, struct open_file *f) +{ + struct efi_devdesc *dev = f->f_devdata; + static EFI_GUID sfsid = SIMPLE_FILE_SYSTEM_PROTOCOL; + EFI_FILE_IO_INTERFACE *sfs; + EFI_FILE *root; + EFI_FILE *file; + EFI_STATUS status; + CHAR16 *cp; + CHAR16 *path; + + /* + * We cannot blindly assume that f->f_devdata points to a + * efi_devdesc structure. Before we dereference 'dev', make + * sure that the underlying device is ours. + */ + if (f->f_dev != &efifs_dev || dev->d_handle == NULL) + return ENOENT; + + status = BS->HandleProtocol(dev->d_handle, &sfsid, (VOID **)&sfs); + if (EFI_ERROR(status)) + return ENOENT; + + /* + * Find the root directory. + */ + status = sfs->OpenVolume(sfs, &root); + + /* + * Convert path to CHAR16, skipping leading separators. + */ + while (*upath == '/') + upath++; + if (!*upath) { + /* Opening the root directory, */ + f->f_fsdata = root; + return 0; + } + cp = path = malloc((strlen(upath) + 1) * sizeof(CHAR16)); + if (path == NULL) + return ENOMEM; + while (*upath) { + if (*upath == '/') + *cp = '\\'; + else + *cp = *upath; + upath++; + cp++; + } + *cp++ = 0; + + /* + * Try to open it. + */ + status = root->Open(root, &file, path, EFI_FILE_MODE_READ, 0); + free(path); + if (EFI_ERROR(status)) { + root->Close(root); + return ENOENT; + } + + root->Close(root); + f->f_fsdata = file; + return 0; +} + +static int +efifs_close(struct open_file *f) +{ + EFI_FILE *file = f->f_fsdata; + + file->Close(file); + return 0; +} + +static int +efifs_read(struct open_file *f, void *buf, size_t size, size_t *resid) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + UINTN sz = size; + char *bufp; + + bufp = buf; + while (size > 0) { + sz = size; + if (sz > EFI_BLOCK_SIZE) + sz = EFI_BLOCK_SIZE; + status = file->Read(file, &sz, bufp); + twiddle(); + if (EFI_ERROR(status)) + return EIO; + if (sz == 0) + break; + size -= sz; + bufp += sz; + } + if (resid) + *resid = size; + return 0; +} + +static int +efifs_write(struct open_file *f, void *buf, size_t size, size_t *resid) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + UINTN sz = size; + char *bufp; + + bufp = buf; + while (size > 0) { + sz = size; + if (sz > EFI_BLOCK_SIZE) + sz = EFI_BLOCK_SIZE; + status = file->Write(file, &sz, bufp); + twiddle(); + if (EFI_ERROR(status)) + return EIO; + if (sz == 0) + break; + size -= sz; + bufp += sz; + } + if (resid) + *resid = size; + return 0; +} + +static off_t +efifs_seek(struct open_file *f, off_t offset, int where) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + UINT64 base; + UINTN sz; + static EFI_GUID infoid = EFI_FILE_INFO_ID; + EFI_FILE_INFO info; + + switch (where) { + case SEEK_SET: + base = 0; + break; + + case SEEK_CUR: + status = file->GetPosition(file, &base); + if (EFI_ERROR(status)) + return -1; + break; + + case SEEK_END: + sz = sizeof(info); + status = file->GetInfo(file, &infoid, &sz, &info); + if (EFI_ERROR(status)) + return -1; + base = info.FileSize; + break; + } + + status = file->SetPosition(file, base + offset); + if (EFI_ERROR(status)) + return -1; + file->GetPosition(file, &base); + + return base; +} + +static int +efifs_stat(struct open_file *f, struct stat *sb) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + char *buf; + UINTN sz; + static EFI_GUID infoid = EFI_FILE_INFO_ID; + EFI_FILE_INFO *info; + + bzero(sb, sizeof(*sb)); + + buf = malloc(1024); + sz = 1024; + + status = file->GetInfo(file, &infoid, &sz, buf); + if (EFI_ERROR(status)) { + free(buf); + return -1; + } + + info = (EFI_FILE_INFO *) buf; + + if (info->Attribute & EFI_FILE_READ_ONLY) + sb->st_mode = S_IRUSR; + else + sb->st_mode = S_IRUSR | S_IWUSR; + if (info->Attribute & EFI_FILE_DIRECTORY) + sb->st_mode |= S_IFDIR; + else + sb->st_mode |= S_IFREG; + sb->st_size = info->FileSize; + + free(buf); + return 0; +} + +static int +efifs_readdir(struct open_file *f, struct dirent *d) +{ + EFI_FILE *file = f->f_fsdata; + EFI_STATUS status; + char *buf; + UINTN sz; + EFI_FILE_INFO *info; + int i; + + buf = malloc(1024); + sz = 1024; + + status = file->Read(file, &sz, buf); + if (EFI_ERROR(status) || sz < offsetof(EFI_FILE_INFO, FileName)) + return ENOENT; + + info = (EFI_FILE_INFO *) buf; + + d->d_fileno = 0; + d->d_reclen = sizeof(*d); + if (info->Attribute & EFI_FILE_DIRECTORY) + d->d_type = DT_DIR; + else + d->d_type = DT_REG; + d->d_namlen = ((info->Size - offsetof(EFI_FILE_INFO, FileName)) + / sizeof(CHAR16)); + for (i = 0; i < d->d_namlen; i++) + d->d_name[i] = info->FileName[i]; + d->d_name[i] = 0; + + free(buf); + return 0; +} + +struct fs_ops efi_fsops = { + "fs", + efifs_open, + efifs_close, + efifs_read, + efifs_write, + efifs_seek, + efifs_stat, + efifs_readdir +}; + +static EFI_HANDLE *fs_handles; +UINTN fs_handle_count; + +int +efifs_get_unit(EFI_HANDLE h) +{ + UINTN u; + + u = 0; + while (u < fs_handle_count && fs_handles[u] != h) + u++; + return ((u < fs_handle_count) ? u : -1); +} + +static int +efifs_dev_init(void) +{ + EFI_STATUS status; + UINTN sz; + static EFI_GUID sfsid = SIMPLE_FILE_SYSTEM_PROTOCOL; + + sz = 0; + status = BS->LocateHandle(ByProtocol, &sfsid, 0, &sz, 0); + if (status != EFI_BUFFER_TOO_SMALL) + return ENOENT; + fs_handles = (EFI_HANDLE *) malloc(sz); + status = BS->LocateHandle(ByProtocol, &sfsid, 0, + &sz, fs_handles); + if (EFI_ERROR(status)) { + free(fs_handles); + return ENOENT; + } + fs_handle_count = sz / sizeof(EFI_HANDLE); + + return 0; +} + +/* + * Print information about disks + */ +static void +efifs_dev_print(int verbose) +{ + int i; + char line[80]; + + for (i = 0; i < fs_handle_count; i++) { + sprintf(line, " fs%d: EFI filesystem", i); + pager_output(line); + /* XXX more detail? */ + pager_output("\n"); + } +} + +/* + * Attempt to open the disk described by (dev) for use by (f). + * + * Note that the philosophy here is "give them exactly what + * they ask for". This is necessary because being too "smart" + * about what the user might want leads to complications. + * (eg. given no slice or partition value, with a disk that is + * sliced - are they after the first BSD slice, or the DOS + * slice before it?) + */ +static int +efifs_dev_open(struct open_file *f, ...) +{ + va_list args; + struct efi_devdesc *dev; + int unit; + + va_start(args, f); + dev = va_arg(args, struct efi_devdesc*); + va_end(args); + + unit = dev->d_kind.efidisk.unit; + if (unit < 0 || unit >= fs_handle_count) { + printf("attempt to open nonexistent EFI filesystem\n"); + return(ENXIO); + } + + dev->d_handle = fs_handles[unit]; + + return 0; +} + +static int +efifs_dev_close(struct open_file *f) +{ + + return 0; +} + +static int +efifs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) +{ + return 0; +} + +struct devsw efifs_dev = { + "fs", + DEVT_DISK, + efifs_dev_init, + efifs_dev_strategy, + efifs_dev_open, + efifs_dev_close, + noioctl, + efifs_dev_print +}; diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c new file mode 100644 index 0000000000..c3db8c6101 --- /dev/null +++ b/sys/boot/efi/libefi/efinet.c @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/boot/efi/libefi/efinet.c,v 1.5 2002/07/20 03:52:18 peter Exp $ + * $DragonFly: src/sys/boot/efi/libefi/efinet.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +extern struct netif_driver efi_net; + +#ifdef EFINET_DEBUG +static void +dump_mode(EFI_SIMPLE_NETWORK_MODE *mode) +{ + int i; + + printf("State = %x\n", mode->State); + printf("HwAddressSize = %u\n", mode->HwAddressSize); + printf("MediaHeaderSize = %u\n", mode->MediaHeaderSize); + printf("MaxPacketSize = %u\n", mode->MaxPacketSize); + printf("NvRamSize = %u\n", mode->NvRamSize); + printf("NvRamAccessSize = %u\n", mode->NvRamAccessSize); + printf("ReceiveFilterMask = %x\n", mode->ReceiveFilterMask); + printf("ReceiveFilterSetting = %u\n", mode->ReceiveFilterSetting); + printf("MaxMCastFilterCount = %u\n", mode->MaxMCastFilterCount); + printf("MCastFilterCount = %u\n", mode->MCastFilterCount); + printf("MCastFilter = {"); + for (i = 0; i < mode->MCastFilterCount; i++) + printf(" %s", ether_sprintf(mode->MCastFilter[i].Addr)); + printf(" }\n"); + printf("CurrentAddress = %s\n", + ether_sprintf(mode->CurrentAddress.Addr)); + printf("BroadcastAddress = %s\n", + ether_sprintf(mode->BroadcastAddress.Addr)); + printf("PermanentAddress = %s\n", + ether_sprintf(mode->PermanentAddress.Addr)); + printf("IfType = %u\n", mode->IfType); + printf("MacAddressChangeable = %d\n", mode->MacAddressChangeable); + printf("MultipleTxSupported = %d\n", mode->MultipleTxSupported); + printf("MediaPresentSupported = %d\n", mode->MediaPresentSupported); + printf("MediaPresent = %d\n", mode->MediaPresent); +} +#endif + +int +efinet_match(struct netif *nif, void *machdep_hint) +{ + + return (1); +} + +int +efinet_probe(struct netif *nif, void *machdep_hint) +{ + + return (0); +} + +int +efinet_put(struct iodesc *desc, void *pkt, size_t len) +{ + struct netif *nif = desc->io_netif; + EFI_SIMPLE_NETWORK *net; + EFI_STATUS status; + void *buf; + + net = nif->nif_devdata; + + status = net->Transmit(net, 0, len, pkt, 0, 0, 0); + if (status != EFI_SUCCESS) + return -1; + + /* Wait for the buffer to be transmitted */ + do { + buf = 0; /* XXX Is this needed? */ + status = net->GetStatus(net, 0, &buf); + /* + * XXX EFI1.1 and the E1000 card returns a different + * address than we gave. Sigh. + */ + } while (status == EFI_SUCCESS && buf == 0); + + /* XXX How do we deal with status != EFI_SUCCESS now? */ + return (status == EFI_SUCCESS) ? len : -1; +} + + +int +efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) +{ + struct netif *nif = desc->io_netif; + EFI_SIMPLE_NETWORK *net; + EFI_STATUS status; + UINTN bufsz; + time_t t; + char buf[2048]; + + net = nif->nif_devdata; + + t = time(0); + while ((time(0) - t) < timeout) { + bufsz = sizeof(buf); + status = net->Receive(net, 0, &bufsz, buf, 0, 0, 0); + if (status == EFI_SUCCESS) { + /* + * XXX EFI1.1 and the E1000 card trash our + * workspace if we do not do this silly copy. + * Either they are not respecting the len + * value or do not like the alignment. + */ + if (bufsz > len) + bufsz = len; + bcopy(buf, pkt, bufsz); + return bufsz; + } + if (status != EFI_NOT_READY) + return 0; + } + + return 0; +} + +void +efinet_init(struct iodesc *desc, void *machdep_hint) +{ + struct netif *nif = desc->io_netif; + EFI_SIMPLE_NETWORK *net; + EFI_STATUS status; + + net = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private; + nif->nif_devdata = net; + + if (net->Mode->State == EfiSimpleNetworkStopped) { + status = net->Start(net); + if (status != EFI_SUCCESS) { + printf("net%d: cannot start interface (status=%ld)\n", + nif->nif_unit, status); + return; + } + } + + if (net->Mode->State != EfiSimpleNetworkInitialized) { + status = net->Initialize(net, 0, 0); + if (status != EFI_SUCCESS) { + printf("net%d: cannot init. interface (status=%ld)\n", + nif->nif_unit, status); + return; + } + } + + if (net->Mode->ReceiveFilterSetting == 0) { + UINT32 mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | + EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; + + status = net->ReceiveFilters(net, mask, 0, FALSE, 0, 0); + if (status != EFI_SUCCESS) { + printf("net%d: cannot set rx. filters (status=%ld)\n", + nif->nif_unit, status); + return; + } + } + +#ifdef EFINET_DEBUG + dump_mode(net->Mode); +#endif + + bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6); + desc->xid = 1; + + return; +} + +void +efinet_init_driver() +{ + EFI_STATUS status; + UINTN sz; + static EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; + EFI_HANDLE *handles; + int nifs, i; +#define MAX_INTERFACES 4 + static struct netif_dif difs[MAX_INTERFACES]; + static struct netif_stats stats[MAX_INTERFACES]; + + sz = 0; + status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, 0); + if (status != EFI_BUFFER_TOO_SMALL) + return; + handles = (EFI_HANDLE *) malloc(sz); + status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, handles); + if (EFI_ERROR(status)) { + free(handles); + return; + } + + nifs = sz / sizeof(EFI_HANDLE); + if (nifs > MAX_INTERFACES) + nifs = MAX_INTERFACES; + + efi_net.netif_nifs = nifs; + efi_net.netif_ifs = difs; + + bzero(stats, sizeof(stats)); + for (i = 0; i < nifs; i++) { + struct netif_dif *dif = &efi_net.netif_ifs[i]; + dif->dif_unit = i; + dif->dif_nsel = 1; + dif->dif_stats = &stats[i]; + + BS->HandleProtocol(handles[i], &netid, + (VOID**) &dif->dif_private); + } + + return; +} + +void +efinet_end(struct netif *nif) +{ + EFI_SIMPLE_NETWORK *net = nif->nif_devdata; + + net->Shutdown(net); +} + +struct netif_driver efi_net = { + "net", /* netif_bname */ + efinet_match, /* netif_match */ + efinet_probe, /* netif_probe */ + efinet_init, /* netif_init */ + efinet_get, /* netif_get */ + efinet_put, /* netif_put */ + efinet_end, /* netif_end */ + 0, /* netif_ifs */ + 0 /* netif_nifs */ +}; + diff --git a/sys/boot/alpha/libalpha/elf_freebsd.c b/sys/boot/efi/libefi/elf_freebsd.c similarity index 51% copy from sys/boot/alpha/libalpha/elf_freebsd.c copy to sys/boot/efi/libefi/elf_freebsd.c index e666644e27..141e32dccc 100644 --- a/sys/boot/alpha/libalpha/elf_freebsd.c +++ b/sys/boot/efi/libefi/elf_freebsd.c @@ -1,6 +1,8 @@ -/* $FreeBSD: src/sys/boot/alpha/libalpha/elf_freebsd.c,v 1.8.2.2 2001/03/04 05:21:25 obrien Exp $ */ -/* $DragonFly: src/sys/boot/alpha/libalpha/Attic/elf_freebsd.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ */ -/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */ +/* + * $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ + * $FreeBSD: src/sys/boot/efi/libefi/elf_freebsd.c,v 1.11 2003/05/01 03:56:29 peter Exp $ + * $DragonFly: src/sys/boot/efi/libefi/elf_freebsd.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -83,79 +85,142 @@ #include #include #include -#include -#include #include +#include +#include +#include + +#include +#include #include "bootstrap.h" #define _KERNEL -static int elf_exec(struct loaded_module *amp); -int bi_load(struct bootinfo_v1 *, vm_offset_t *, - struct loaded_module *); - -struct module_format alpha_elf = { elf_loadmodule, elf_exec }; +static int elf64_exec(struct preloaded_file *amp); -vm_offset_t ffp_save, ptbr_save; +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; -static int -elf_exec(struct loaded_module *mp) +static __inline u_int64_t +disable_ic() { - static struct bootinfo_v1 bootinfo_v1; - struct module_metadata *md; - Elf_Ehdr *hdr; - int err; - int flen; - - if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL) - return(EFTYPE); /* XXX actually EFUCKUP */ - hdr = (Elf_Ehdr *)&(md->md_data); - - /* XXX ffp_save does not appear to be used in the kernel.. */ - bzero(&bootinfo_v1, sizeof(bootinfo_v1)); - err = bi_load(&bootinfo_v1, &ffp_save, mp); - if (err) - return(err); - - /* - * Fill in rest of bootinfo for the kernel. - */ - flen = prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags, - sizeof(bootinfo_v1.boot_flags)); - bootinfo_v1.hwrpb = (void *)HWRPB_ADDR; - bootinfo_v1.hwrpbsize = ((struct rpb *)HWRPB_ADDR)->rpb_size; - bootinfo_v1.cngetc = NULL; - bootinfo_v1.cnputc = NULL; - bootinfo_v1.cnpollc = NULL; - - /* - * Append the boot command flags. - */ - if (mp->m_args != NULL && *mp->m_args != '\0') { - const char *p = mp->m_args; - - do { - if (*p == '-') { - while (*++p != ' ' && *p != '\0') - if (flen < sizeof(bootinfo_v1.boot_flags) - 1) - bootinfo_v1.boot_flags[flen++] = *p; - } else - while (*p != ' ' && *p != '\0') - p++; - while (*p == ' ') - p++; - } while (*p != '\0'); - bootinfo_v1.boot_flags[flen] = '\0'; - } - - printf("Entering %s at 0x%lx...\n", mp->m_name, hdr->e_entry); - closeall(); - dev_cleanup(); - alpha_pal_imb(); - (*(void (*)())hdr->e_entry)(ffp_save, ptbr_save, - BOOTINFO_MAGIC, &bootinfo_v1, 1, 0); + u_int64_t psr; + __asm __volatile("mov %0=psr;;" : "=r" (psr)); + __asm __volatile("rsm psr.ic|psr.i;; srlz.i;;"); + return psr; } +static __inline void +restore_ic(u_int64_t psr) +{ + __asm __volatile("mov psr.l=%0;; srlz.i" :: "r" (psr)); +} +/* + * Entered with psr.ic and psr.i both zero. + */ +void +enter_kernel(u_int64_t start, struct bootinfo *bi) +{ + u_int64_t psr; + + __asm __volatile("srlz.i;;"); + __asm __volatile("mov cr.ipsr=%0" + :: "r"(IA64_PSR_IC + | IA64_PSR_DT + | IA64_PSR_RT + | IA64_PSR_IT + | IA64_PSR_BN)); + __asm __volatile("mov cr.iip=%0" :: "r"(start)); + __asm __volatile("mov cr.ifs=r0;;"); + __asm __volatile("mov ar.rsc=0;; flushrs;;"); + __asm __volatile("mov r8=%0" :: "r" (bi)); + __asm __volatile("rfi;;"); +} +static int +elf64_exec(struct preloaded_file *fp) +{ + struct file_metadata *md; + Elf_Ehdr *hdr; + struct ia64_pte pte; + struct bootinfo *bi; + u_int64_t psr; + UINTN mapkey, pages, size; + UINTN descsz; + UINT32 descver; + EFI_STATUS status; + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return(EFTYPE); /* XXX actually EFUCKUP */ + hdr = (Elf_Ehdr *)&(md->md_data); + + /* + * Allocate enough pages to hold the bootinfo block and the memory + * map EFI will return to us. The memory map has an unknown size, + * so we have to determine that first. Note that the AllocatePages + * call can itself modify the memory map, so we have to take that + * into account as well. The changes to the memory map are caused + * by splitting a range of free memory into two (AFAICT), so that + * one is marked as being loader data. + */ + size = 0; + descsz = sizeof(EFI_MEMORY_DESCRIPTOR); + BS->GetMemoryMap(&size, NULL, &mapkey, &descsz, &descver); + size += descsz + ((sizeof(struct bootinfo) + 0x0f) & ~0x0f); + pages = EFI_SIZE_TO_PAGES(size); + status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages, + (void*)&bi); + if (EFI_ERROR(status)) { + printf("unable to create bootinfo block (status=0x%lx)\n", + (long)status); + return (ENOMEM); + } + + bzero(bi, sizeof(struct bootinfo)); + bi_load(bi, fp, &mapkey, pages); + + printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); + + status = BS->ExitBootServices(IH, mapkey); + if (EFI_ERROR(status)) { + printf("ExitBootServices returned 0x%lx\n", status); + return (EINVAL); + } + + psr = disable_ic(); + + /* + * Region 6 is direct mapped UC and region 7 is direct mapped + * WC. The details of this is controlled by the Alt {I,D}TLB + * handlers. Here we just make sure that they have the largest + * possible page size to minimise TLB usage. + */ + ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); + ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); + + bzero(&pte, sizeof(pte)); + pte.pte_p = 1; + pte.pte_ma = PTE_MA_WB; + pte.pte_a = 1; + pte.pte_d = 1; + pte.pte_pl = PTE_PL_KERN; + pte.pte_ar = PTE_AR_RWX; + pte.pte_ppn = 0; + + __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_RR_BASE(7))); + __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2)); + __asm __volatile("ptr.i %0,%1" :: "r"(IA64_RR_BASE(7)), "r"(28<<2)); + __asm __volatile("ptr.d %0,%1" :: "r"(IA64_RR_BASE(7)), "r"(28<<2)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.i itr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.d dtr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + + enter_kernel(hdr->e_entry, bi); + + restore_ic(psr); +} diff --git a/sys/boot/efi/libefi/libefi.c b/sys/boot/efi/libefi/libefi.c new file mode 100644 index 0000000000..9f47f73066 --- /dev/null +++ b/sys/boot/efi/libefi/libefi.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $DragonFly: src/sys/boot/efi/libefi/libefi.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include + +EFI_HANDLE IH; +EFI_SYSTEM_TABLE *ST; +EFI_BOOT_SERVICES *BS; +EFI_RUNTIME_SERVICES *RS; + +static EFI_PHYSICAL_ADDRESS heap; +static UINTN heapsize; + +static CHAR16 * +arg_skipsep(CHAR16 *argp) +{ + + while (*argp == ' ' || *argp == '\t') + argp++; + return (argp); +} + +static CHAR16 * +arg_skipword(CHAR16 *argp) +{ + + while (*argp && *argp != ' ' && *argp != '\t') + argp++; + return (argp); +} + +void * +efi_get_table(EFI_GUID *tbl) +{ + EFI_GUID *id; + int i; + + for (i = 0; i < ST->NumberOfTableEntries; i++) { + id = &ST->ConfigurationTable[i].VendorGuid; + if (!memcmp(id, tbl, sizeof(EFI_GUID))) + return (ST->ConfigurationTable[i].VendorTable); + } + return (NULL); +} + +void exit(EFI_STATUS exit_code) +{ + + BS->FreePages(heap, EFI_SIZE_TO_PAGES(heapsize)); + BS->Exit(IH, exit_code, 0, NULL); +} + +void +efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) +{ + static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL; + EFI_LOADED_IMAGE *img; + CHAR16 *argp, *args, **argv; + EFI_STATUS status; + int argc, addprog; + + IH = image_handle; + ST = system_table; + BS = ST->BootServices; + RS = ST->RuntimeServices; + + heapsize = 512*1024; + status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, + EFI_SIZE_TO_PAGES(heapsize), &heap); + if (status != EFI_SUCCESS) + BS->Exit(IH, status, 0, NULL); + + setheap((void *)heap, (void *)(heap + heapsize)); + + /* Use exit() from here on... */ + + status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img); + if (status != EFI_SUCCESS) + exit(status); + + /* + * Pre-process the (optional) load options. If the option string + * is given as an ASCII string, we use a poor man's ASCII to + * Unicode-16 translation. The size of the option string as given + * to us includes the terminating null character. We assume the + * string is an ASCII string if strlen() plus the terminating + * '\0' is less than LoadOptionsSize. Even if all Unicode-16 + * characters have the upper 8 bits non-zero, the terminating + * null character will cause a one-off. + * If the string is already in Unicode-16, we make a copy so that + * we know we can always modify the string. + */ + if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) { + if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) { + args = malloc(img->LoadOptionsSize << 1); + for (argc = 0; argc < img->LoadOptionsSize; argc++) + args[argc] = ((char*)img->LoadOptions)[argc]; + } else { + args = malloc(img->LoadOptionsSize); + memcpy(args, img->LoadOptions, img->LoadOptionsSize); + } + } else + args = NULL; + + /* + * Use a quick and dirty algorithm to build the argv vector. We + * first count the number of words. Then, after allocating the + * vector, we split the string up. We don't deal with quotes or + * other more advanced shell features. + * The EFI shell will pas the name of the image as the first + * word in the argument list. This does not happen if we're + * loaded by the boot manager. This is not so easy to figure + * out though. The ParentHandle is not always NULL, because + * there can be a function (=image) that will perform the task + * for the boot manager. + */ + /* Part 1: Figure out if we need to add our program name. */ + addprog = (args == NULL || img->ParentHandle == NULL || + img->FilePath == NULL) ? 1 : 0; + if (!addprog) { + addprog = + (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH || + DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP || + DevicePathNodeLength(img->FilePath) <= + sizeof(FILEPATH_DEVICE_PATH)) ? 1 : 0; + if (!addprog) { + /* XXX todo. */ + } + } + /* Part 2: count words. */ + argc = (addprog) ? 1 : 0; + argp = args; + while (argp != NULL && *argp != 0) { + argp = arg_skipsep(argp); + if (*argp == 0) + break; + argc++; + argp = arg_skipword(argp); + } + /* Part 3: build vector. */ + argv = malloc((argc + 1) * sizeof(CHAR16*)); + argc = 0; + if (addprog) + argv[argc++] = L"loader.efi"; + argp = args; + while (argp != NULL && *argp != 0) { + argp = arg_skipsep(argp); + if (*argp == 0) + break; + argv[argc++] = argp; + argp = arg_skipword(argp); + /* Terminate the words. */ + if (*argp != 0) + *argp++ = 0; + } + argv[argc] = NULL; + + status = main(argc, argv); + exit(status); +} diff --git a/sys/boot/common/dev_net.h b/sys/boot/efi/libefi/module.c similarity index 81% copy from sys/boot/common/dev_net.h copy to sys/boot/efi/libefi/module.c index 803d405dea..90d75029c3 100644 --- a/sys/boot/common/dev_net.h +++ b/sys/boot/efi/libefi/module.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998 Doug Rabson + * Copyright (c) 1998 Michael Smith * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,9 +23,17 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/common/dev_net.h,v 1.2 1999/08/28 00:39:46 peter Exp $ - * $DragonFly: src/sys/boot/common/dev_net.h,v 1.2 2003/06/17 04:28:16 dillon Exp $ + * $DragonFly: src/sys/boot/efi/libefi/module.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ */ -extern struct devsw netdev; +#include +/* + * Use voodoo to load modules required by current hardware. + */ +int +efi_autoload(void) +{ + /* XXX use PnP to locate stuff here */ + return (0); +} diff --git a/sys/boot/efi/libefi/time.c b/sys/boot/efi/libefi/time.c new file mode 100644 index 0000000000..288589bd20 --- /dev/null +++ b/sys/boot/efi/libefi/time.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 1999, 2000 + * Intel Corporation. + * All rights reserved. + * + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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. + * + * $DragonFly: src/sys/boot/efi/libefi/time.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include + +#include +#include + +/* +// Accurate only for the past couple of centuries; +// that will probably do. +// +// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) +*/ + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERHOUR ( 60*60 ) +#define SECSPERDAY (24 * SECSPERHOUR) + +time_t +EfiTimeToUnixTime(EFI_TIME *ETime) +{ + /* + // These arrays give the cumulative number of days up to the first of the + // month number used as the index (1 -> 12) for regular and leap years. + // The value at index 13 is for the whole year. + */ + static time_t CumulativeDays[2][14] = { + {0, + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, + {0, + 0, + 31, + 31 + 29, + 31 + 29 + 31, + 31 + 29 + 31 + 30, + 31 + 29 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; + + time_t UTime; + int Year; + + /* + // Do a santity check + */ + if ( ETime->Year < 1998 || ETime->Year > 2099 || + ETime->Month == 0 || ETime->Month > 12 || + ETime->Day == 0 || ETime->Month > 31 || + ETime->Hour > 23 || + ETime->Minute > 59 || + ETime->Second > 59 || + ETime->TimeZone < -1440 || + (ETime->TimeZone > 1440 && ETime->TimeZone != 2047) ) { + return (0); + } + + /* + // Years + */ + UTime = 0; + for (Year = 1970; Year != ETime->Year; ++Year) { + UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); + } + + /* + // UTime should now be set to 00:00:00 on Jan 1 of the file's year. + // + // Months + */ + UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); + + /* + // UTime should now be set to 00:00:00 on the first of the file's month and year + // + // Days -- Don't count the file's day + */ + UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); + + /* + // Hours + */ + UTime += (ETime->Hour * SECSPERHOUR); + + /* + // Minutes + */ + UTime += (ETime->Minute * 60); + + /* + // Seconds + */ + UTime += ETime->Second; + + /* + // EFI time is repored in local time. Adjust for any time zone offset to + // get true UT + */ + if ( ETime->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) { + /* + // TimeZone is kept in minues... + */ + UTime += (ETime->TimeZone * 60); + } + + return UTime; +} + +int +EFI_GetTimeOfDay( + OUT struct timeval *tp, + OUT struct timezone *tzp + ) +{ + EFI_TIME EfiTime; + EFI_TIME_CAPABILITIES Capabilities; + EFI_STATUS Status; + + /* + // Get time from EFI + */ + + Status = RS->GetTime( &EfiTime, &Capabilities ); + if (EFI_ERROR(Status)) + return (-1); + + /* + // Convert to UNIX time (ie seconds since the epoch + */ + + tp->tv_sec = EfiTimeToUnixTime( &EfiTime ); + tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */ + + /* + // Do something with the timezone if needed + */ + + if (tzp) { + tzp->tz_minuteswest = + EfiTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE ? 0 : EfiTime.TimeZone; + /* + // This isn't quit right since it doesn't deal with EFI_TIME_IN_DAYLIGHT + */ + tzp->tz_dsttime = + EfiTime.Daylight & EFI_TIME_ADJUST_DAYLIGHT ? 1 : 0; + } + + return (0); +} + +time_t +time(time_t *tloc) +{ + struct timeval tv; + EFI_GetTimeOfDay(&tv, 0); + + if (tloc) + *tloc = tv.tv_sec; + return tv.tv_sec; +} + +time_t +getsecs() +{ + return time(0); +} diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile new file mode 100644 index 0000000000..50cf2da49d --- /dev/null +++ b/sys/boot/efi/loader/Makefile @@ -0,0 +1,124 @@ +# $FreeBSD$ +# $DragonFly: src/sys/boot/efi/loader/Makefile,v 1.1 2003/11/10 06:08:33 dillon Exp $ + +.PATH: ${.CURDIR}/../common + +BASE= loader +PROG= ${BASE}.efi +NOMAN= +NEWVERSWHAT= "EFI boot" ${MACHINE_ARCH} +BINDIR?= /boot +STRIP= # We must not strip loader.efi at install time. + +SRCS+= main.c conf.c dev_net.c + +CFLAGS+= -ffreestanding + +.if !defined(NOFORTH) +# Enable BootForth +BOOT_FORTH= yes +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE_ARCH} +.if exists(${.OBJDIR}/../../ficl/libficl.a) +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.else +LIBFICL= ${.CURDIR}/../../ficl/libficl.a +.endif +.endif + +# where to get libstand from +.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a) +LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a +.else +LIBSTAND= ${.CURDIR}/../../../../lib/libstand/libstand.a +.endif + +.if exists(${.OBJDIR}/../libefi/libefi.a) +LIBEFI= ${.OBJDIR}/../libefi/libefi.a +.else +LIBEFI= ${.CURDIR}/../libefi/libefi.a +.endif + +# Always add MI sources +.PATH: ${.CURDIR}/../../common +.include <${.CURDIR}/../../common/Makefile.inc> + +CFLAGS+= -I- +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH} +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR} +CFLAGS+= -I${.CURDIR}/../../.. -I. +CFLAGS+= -I${.CURDIR}/../libefi +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand +CFLAGS+= -DLOADER + +LDSCRIPT= ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/ldscript.${MACHINE_ARCH} +LDFLAGS= -nostdlib -T ${LDSCRIPT} -shared -Bsymbolic +OBJCOPY?= objcopy + +CLEANFILES+= setdef0.c setdef0.o setdef1.c setdef1.o setdefs.h start.o \ + vers.c vers.o ${BASE}.efi ${BASE}.sym ${BASE}.list +CLEANFILES+= loader.help +CLEANFILES+= machine + +CRT= start.o + +all: ${BASE} + +vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + ${CC} -c vers.c + +${BASE}: ${BASE}.efi ${BASE}.help + +${BASE}.efi: ${BASE}.sym + ${OBJCOPY} -j .text \ + -j .hash \ + -j .data \ + -j .sdata \ + -j .dynamic \ + -j .rela \ + -j .reloc \ + -j .dynsym \ + -j .dynstr \ + --target=efi-app-${MACHINE_ARCH} \ + ${BASE}.sym ${BASE}.efi + +${BASE}.help: help.common + cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \ + > ${.TARGET} + +beforeinstall: +.if exists(${.OBJDIR}/loader.help) + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.OBJDIR}/${BASE}.help ${DESTDIR}/boot +.else + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/${BASE}.help ${DESTDIR}/boot +.endif +.if !exists(${DESTDIR}/boot/loader.rc) + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/loader.rc ${DESTDIR}/boot +.endif + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/loader.4th ${DESTDIR}/boot + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/support.4th ${DESTDIR}/boot + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.CURDIR}/../../forth/loader.conf ${DESTDIR}/boot/defaults + + +# Other fragments still to be brought in from ../Makfile.booters? +start.o: ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/start.S + ${CC} -c ${CFLAGS} ${.IMPSRC} + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +.include + +${BASE}.sym: ${OBJS} ${LIBFICL} ${LIBEFI} ${LIBSTAND} ${CRT} vers.o + ${LD} ${LDFLAGS} -o ${BASE}.sym -M ${CRT} ${OBJS} vers.o \ + ${LIBFICL} ${LIBEFI} ${LIBSTAND} > ${.OBJDIR}/${BASE}.list + +beforedepend ${OBJS}: machine diff --git a/sys/boot/arc/loader/conf.c b/sys/boot/efi/loader/conf.c similarity index 79% copy from sys/boot/arc/loader/conf.c copy to sys/boot/efi/loader/conf.c index 32df1e780c..9f953e3046 100644 --- a/sys/boot/arc/loader/conf.c +++ b/sys/boot/efi/loader/conf.c @@ -1,9 +1,3 @@ -/* - * $FreeBSD: src/sys/boot/arc/loader/conf.c,v 1.2 1999/08/28 00:39:42 peter Exp $ - * $DragonFly: src/sys/boot/arc/loader/Attic/conf.c,v 1.2 2003/06/17 04:28:16 dillon Exp $ - * From $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ - */ - /* * Copyright (c) 1997 * Matthias Drochner. All rights reserved. @@ -33,11 +27,16 @@ * 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. + * + * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ + * $DragonFly: src/sys/boot/efi/loader/conf.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ */ - #include -#include "libarc.h" +#include +#include + +#include "efiboot.h" /* * We could use linker sets for some or all of these, but @@ -50,37 +49,45 @@ /* Exported for libstand */ struct devsw *devsw[] = { - &arcdisk, - NULL + &efifs_dev, + &netdev, + NULL }; struct fs_ops *file_system[] = { - &ufs_fsops, - &zipfs_fsops, - NULL + &efi_fsops, +/* &ufs_fsops, */ + &nfs_fsops, + &gzipfs_fsops, + NULL +}; + +struct netif_driver *netif_drivers[] = { + &efi_net, + NULL, }; -/* Exported for alpha only */ +/* Exported for ia64 only */ /* * Sort formats so that those that can detect based on arguments * rather than reading the file go first. */ -extern struct module_format alpha_elf; +extern struct file_format ia64_elf; -struct module_format *module_formats[] = { - &alpha_elf, - NULL +struct file_format *file_formats[] = { + &ia64_elf, + NULL }; /* * Consoles * - * We don't prototype these in libalpha.h because they require + * We don't prototype these in efiboot.h because they require * data structures from bootstrap.h as well. */ -extern struct console arcconsole; +extern struct console efi_console; struct console *consoles[] = { - &arcconsole, - NULL + &efi_console, + NULL }; diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c new file mode 100644 index 0000000000..703b58a511 --- /dev/null +++ b/sys/boot/efi/loader/main.c @@ -0,0 +1,562 @@ +/*- + * Copyright (c) 1998 Michael Smith + * Copyright (c) 1998,2000 Doug Rabson + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/boot/efi/loader/main.c,v 1.20 2003/08/02 08:22:03 marcel Exp $ + * $DragonFly: src/sys/boot/efi/loader/main.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "bootstrap.h" +#include "efiboot.h" + +extern char bootprog_name[]; +extern char bootprog_rev[]; +extern char bootprog_date[]; +extern char bootprog_maker[]; + +struct efi_devdesc currdev; /* our current device */ +struct arch_switch archsw; /* MI/MD interface boundary */ + +extern u_int64_t ia64_pal_entry; + +EFI_GUID acpi = ACPI_TABLE_GUID; +EFI_GUID acpi20 = ACPI_20_TABLE_GUID; +EFI_GUID devid = DEVICE_PATH_PROTOCOL; +EFI_GUID hcdp = HCDP_TABLE_GUID; +EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; +EFI_GUID mps = MPS_TABLE_GUID; +EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; +EFI_GUID sal = SAL_SYSTEM_TABLE_GUID; +EFI_GUID smbios = SMBIOS_TABLE_GUID; + +static void +find_pal_proc(void) +{ + int i; + struct sal_system_table *saltab = 0; + static int sizes[6] = { + 48, 32, 16, 32, 16, 16 + }; + u_int8_t *p; + + saltab = efi_get_table(&sal); + if (saltab == NULL) { + printf("Can't find SAL System Table\n"); + return; + } + + if (memcmp(saltab->sal_signature, "SST_", 4)) { + printf("Bad signature for SAL System Table\n"); + return; + } + + p = (u_int8_t *) (saltab + 1); + for (i = 0; i < saltab->sal_entry_count; i++) { + if (*p == 0) { + struct sal_entrypoint_descriptor *dp; + dp = (struct sal_entrypoint_descriptor *) p; + ia64_pal_entry = dp->sale_pal_proc; + return; + } + p += sizes[*p]; + } + + printf("Can't find PAL proc\n"); + return; +} + +EFI_STATUS +main(int argc, CHAR16 *argv[]) +{ + EFI_LOADED_IMAGE *img; + int i; + + /* + * XXX Chicken-and-egg problem; we want to have console output + * early, but some console attributes may depend on reading from + * eg. the boot device, which we can't do yet. We can use + * printf() etc. once this is done. + */ + cons_probe(); + + /* + * Initialise the block cache + */ + bcache_init(32, 512); /* 16k XXX tune this */ + + find_pal_proc(); + + /* + * March through the device switch probing for things. + */ + for (i = 0; devsw[i] != NULL; i++) + if (devsw[i]->dv_init != NULL) + (devsw[i]->dv_init)(); + + efinet_init_driver(); + + /* Get our loaded image protocol interface structure. */ + BS->HandleProtocol(IH, &imgid, (VOID**)&img); + + printf("Image base: 0x%016lx\n", (u_long)img->ImageBase); + + printf("\n"); + printf("%s, Revision %s\n", bootprog_name, bootprog_rev); + printf("(%s, %s)\n", bootprog_maker, bootprog_date); + + i = efifs_get_unit(img->DeviceHandle); + if (i >= 0) { + currdev.d_dev = devsw[0]; /* XXX disk */ + currdev.d_kind.efidisk.unit = i; + /* XXX should be able to detect this, default to autoprobe */ + currdev.d_kind.efidisk.slice = -1; + currdev.d_kind.efidisk.partition = 0; + } else { + currdev.d_dev = devsw[1]; /* XXX net */ + currdev.d_kind.netif.unit = 0; /* XXX */ + } + currdev.d_type = currdev.d_dev->dv_type; + + /* + * Disable the watchdog timer. By default the boot manager sets + * the timer to 5 minutes before invoking a boot option. If we + * want to return to the boot manager, we have to disable the + * watchdog timer and since we're an interactive program, we don't + * want to wait until the user types "quit". The timer may have + * fired by then. We don't care if this fails. It does not prevent + * normal functioning in any way... + */ + BS->SetWatchdogTimer(0, 0, 0, NULL); + + env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), + efi_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, + env_nounset); + + setenv("LINES", "24", 1); /* optional */ + + archsw.arch_autoload = efi_autoload; + archsw.arch_getdev = efi_getdev; + archsw.arch_copyin = efi_copyin; + archsw.arch_copyout = efi_copyout; + archsw.arch_readin = efi_readin; + + interact(); /* doesn't return */ + + return (EFI_SUCCESS); /* keep compiler happy */ +} + +COMMAND_SET(quit, "quit", "exit the loader", command_quit); + +static int +command_quit(int argc, char *argv[]) +{ + exit(0); + return (CMD_OK); +} + +COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); + +static int +command_memmap(int argc, char *argv[]) +{ + UINTN sz; + EFI_MEMORY_DESCRIPTOR *map, *p; + UINTN key, dsz; + UINT32 dver; + EFI_STATUS status; + int i, ndesc; + static char *types[] = { + "Reserved", + "LoaderCode", + "LoaderData", + "BootServicesCode", + "BootServicesData", + "RuntimeServicesCode", + "RuntimeServicesData", + "ConventionalMemory", + "UnusableMemory", + "ACPIReclaimMemory", + "ACPIMemoryNVS", + "MemoryMappedIO", + "MemoryMappedIOPortSpace", + "PalCode" + }; + + sz = 0; + status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); + if (status != EFI_BUFFER_TOO_SMALL) { + printf("Can't determine memory map size\n"); + return CMD_ERROR; + } + map = malloc(sz); + status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); + if (EFI_ERROR(status)) { + printf("Can't read memory map\n"); + return CMD_ERROR; + } + + ndesc = sz / dsz; + printf("%23s %12s %12s %8s %4s\n", + "Type", "Physical", "Virtual", "#Pages", "Attr"); + + for (i = 0, p = map; i < ndesc; + i++, p = NextMemoryDescriptor(p, dsz)) { + printf("%23s %012lx %012lx %08lx ", + types[p->Type], + p->PhysicalStart, + p->VirtualStart, + p->NumberOfPages); + if (p->Attribute & EFI_MEMORY_UC) + printf("UC "); + if (p->Attribute & EFI_MEMORY_WC) + printf("WC "); + if (p->Attribute & EFI_MEMORY_WT) + printf("WT "); + if (p->Attribute & EFI_MEMORY_WB) + printf("WB "); + if (p->Attribute & EFI_MEMORY_UCE) + printf("UCE "); + if (p->Attribute & EFI_MEMORY_WP) + printf("WP "); + if (p->Attribute & EFI_MEMORY_RP) + printf("RP "); + if (p->Attribute & EFI_MEMORY_XP) + printf("XP "); + if (p->Attribute & EFI_MEMORY_RUNTIME) + printf("RUNTIME"); + printf("\n"); + } + + return CMD_OK; +} + +COMMAND_SET(configuration, "configuration", + "print configuration tables", command_configuration); + +static const char * +guid_to_string(EFI_GUID *guid) +{ + static char buf[40]; + + sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], + guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], + guid->Data4[5], guid->Data4[6], guid->Data4[7]); + return (buf); +} + +static int +command_configuration(int argc, char *argv[]) +{ + int i; + + printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries); + for (i = 0; i < ST->NumberOfTableEntries; i++) { + EFI_GUID *guid; + + printf(" "); + guid = &ST->ConfigurationTable[i].VendorGuid; + if (!memcmp(guid, &mps, sizeof(EFI_GUID))) + printf("MPS Table"); + else if (!memcmp(guid, &acpi, sizeof(EFI_GUID))) + printf("ACPI Table"); + else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) + printf("ACPI 2.0 Table"); + else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) + printf("SMBIOS Table"); + else if (!memcmp(guid, &sal, sizeof(EFI_GUID))) + printf("SAL System Table"); + else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID))) + printf("DIG64 HCDP Table"); + else + printf("Unknown Table (%s)", guid_to_string(guid)); + printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); + } + + return CMD_OK; +} + +COMMAND_SET(sal, "sal", "print SAL System Table", command_sal); + +static int +command_sal(int argc, char *argv[]) +{ + int i; + struct sal_system_table *saltab = 0; + static int sizes[6] = { + 48, 32, 16, 32, 16, 16 + }; + u_int8_t *p; + + saltab = efi_get_table(&sal); + if (saltab == NULL) { + printf("Can't find SAL System Table\n"); + return CMD_ERROR; + } + + if (memcmp(saltab->sal_signature, "SST_", 4)) { + printf("Bad signature for SAL System Table\n"); + return CMD_ERROR; + } + + printf("SAL Revision %x.%02x\n", + saltab->sal_rev[1], + saltab->sal_rev[0]); + printf("SAL A Version %x.%02x\n", + saltab->sal_a_version[1], + saltab->sal_a_version[0]); + printf("SAL B Version %x.%02x\n", + saltab->sal_b_version[1], + saltab->sal_b_version[0]); + + p = (u_int8_t *) (saltab + 1); + for (i = 0; i < saltab->sal_entry_count; i++) { + printf(" Desc %d", *p); + if (*p == 0) { + struct sal_entrypoint_descriptor *dp; + dp = (struct sal_entrypoint_descriptor *) p; + printf("\n"); + printf(" PAL Proc at 0x%lx\n", + dp->sale_pal_proc); + printf(" SAL Proc at 0x%lx\n", + dp->sale_sal_proc); + printf(" SAL GP at 0x%lx\n", + dp->sale_sal_gp); + } else if (*p == 1) { + struct sal_memory_descriptor *dp; + dp = (struct sal_memory_descriptor *) p; + printf(" Type %d.%d, ", + dp->sale_memory_type[0], + dp->sale_memory_type[1]); + printf("Address 0x%lx, ", + dp->sale_physical_address); + printf("Length 0x%x\n", + dp->sale_length); + } else if (*p == 5) { + struct sal_ap_wakeup_descriptor *dp; + dp = (struct sal_ap_wakeup_descriptor *) p; + printf("\n"); + printf(" Mechanism %d\n", dp->sale_mechanism); + printf(" Vector 0x%lx\n", dp->sale_vector); + } else + printf("\n"); + + p += sizes[*p]; + } + + return CMD_OK; +} + +int +print_trs(int type) +{ + struct ia64_pal_result res; + int i, maxtr; + struct { + struct ia64_pte pte; + struct ia64_itir itir; + struct ia64_ifa ifa; + struct ia64_rr rr; + } buf; + static const char* psnames[] = { + "1B", "2B", "4B", "8B", + "16B", "32B", "64B", "128B", + "256B", "512B", "1K", "2K", + "4K", "8K", "16K", "32K", + "64K", "128K", "256K", "512K", + "1M", "2M", "4M", "8M", + "16M", "32M", "64M", "128M", + "256M", "512M", "1G", "2G" + }; + static const char* manames[] = { + "WB", "bad", "bad", "bad", + "UC", "UCE", "WC", "NaT", + + }; + + res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0); + if (res.pal_status != 0) { + printf("Can't get VM summary\n"); + return CMD_ERROR; + } + + if (type == 0) + maxtr = (res.pal_result[0] >> 40) & 0xff; + else + maxtr = (res.pal_result[0] >> 32) & 0xff; + + printf("%d translation registers\n", maxtr); + + pager_open(); + pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n"); + for (i = 0; i <= maxtr; i++) { + char lbuf[128]; + + bzero(&buf, sizeof(buf)); + res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type, + (u_int64_t) &buf); + if (res.pal_status != 0) + break; + + /* Only display valid translations */ + if ((buf.ifa.ifa_ig & 1) == 0) + continue; + + if (!(res.pal_result[0] & 1)) + buf.pte.pte_ar = 0; + if (!(res.pal_result[0] & 2)) + buf.pte.pte_pl = 0; + if (!(res.pal_result[0] & 4)) + buf.pte.pte_d = 0; + if (!(res.pal_result[0] & 8)) + buf.pte.pte_ma = 0; + sprintf(lbuf, + "%03d %06x %013lx %013lx %4s %d %d %d %d %d %-3s %d %06x\n", + i, + buf.rr.rr_rid, + buf.ifa.ifa_vpn, + buf.pte.pte_ppn, + psnames[buf.itir.itir_ps], + buf.pte.pte_ed, + buf.pte.pte_ar, + buf.pte.pte_pl, + buf.pte.pte_d, + buf.pte.pte_a, + manames[buf.pte.pte_ma], + buf.pte.pte_p, + buf.itir.itir_key); + pager_output(lbuf); + } + pager_close(); + + if (res.pal_status != 0) { + printf("Error while getting TR contents\n"); + return CMD_ERROR; + } + return CMD_OK; +} + +COMMAND_SET(itr, "itr", "print instruction TRs", command_itr); + +static int +command_itr(int argc, char *argv[]) +{ + return print_trs(0); +} + +COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr); + +static int +command_dtr(int argc, char *argv[]) +{ + return print_trs(1); +} + +COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp); + +static char * +hcdp_string(char *s, u_int len) +{ + static char buffer[256]; + + memcpy(buffer, s, len); + buffer[len] = 0; + return (buffer); +} + +static int +command_hcdp(int argc, char *argv[]) +{ + struct dig64_hcdp_table *tbl; + struct dig64_hcdp_entry *ent; + struct dig64_gas *gas; + int i; + + tbl = efi_get_table(&hcdp); + if (tbl == NULL) { + printf("No HCDP table present\n"); + return (CMD_OK); + } + if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) { + printf("HCDP table has invalid signature\n"); + return (CMD_OK); + } + if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) { + printf("HCDP table too short\n"); + return (CMD_OK); + } + printf("HCDP table at 0x%016lx\n", (u_long)tbl); + printf("Signature = %s\n", hcdp_string(tbl->signature, 4)); + printf("Length = %u\n", tbl->length); + printf("Revision = %u\n", tbl->revision); + printf("Checksum = %u\n", tbl->checksum); + printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6)); + printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8)); + printf("OEM rev = %u\n", tbl->oem_rev); + printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4)); + printf("Creator rev= %u\n", tbl->creator_rev); + printf("Entries = %u\n", tbl->entries); + for (i = 0; i < tbl->entries; i++) { + ent = tbl->entry + i; + printf("Entry #%d:\n", i + 1); + printf(" Type = %u\n", ent->type); + printf(" Databits = %u\n", ent->databits); + printf(" Parity = %u\n", ent->parity); + printf(" Stopbits = %u\n", ent->stopbits); + printf(" PCI seg = %u\n", ent->pci_segment); + printf(" PCI bus = %u\n", ent->pci_bus); + printf(" PCI dev = %u\n", ent->pci_device); + printf(" PCI func = %u\n", ent->pci_function); + printf(" Interrupt = %u\n", ent->interrupt); + printf(" PCI flag = %u\n", ent->pci_flag); + printf(" Baudrate = %lu\n", + ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low); + gas = &ent->address; + printf(" Addr space= %u\n", gas->addr_space); + printf(" Bit width = %u\n", gas->bit_width); + printf(" Bit offset= %u\n", gas->bit_offset); + printf(" Address = 0x%016lx\n", + ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low); + printf(" PCI type = %u\n", ent->pci_devid); + printf(" PCI vndr = %u\n", ent->pci_vendor); + printf(" IRQ = %u\n", ent->irq); + printf(" PClock = %u\n", ent->pclock); + printf(" PCI iface = %u\n", ent->pci_interface); + } + printf("\n"); + return (CMD_OK); +} diff --git a/sys/boot/efi/loader/version b/sys/boot/efi/loader/version new file mode 100644 index 0000000000..b9aa9d7456 --- /dev/null +++ b/sys/boot/efi/loader/version @@ -0,0 +1,17 @@ +$FreeBSD: src/sys/boot/efi/loader/version,v 1.5 2002/12/10 20:11:20 marcel Exp $ +$DragonFly: src/sys/boot/efi/loader/version,v 1.1 2003/11/10 06:08:33 dillon Exp $ + +NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this +file is important. Make sure the current version number is on line 6. + +1.1: Pass the HCDP table address to the kernel via bootinfo if one + is present in the EFI system table. +1.0: Don't map the I/O port range. We expect the kernel to do it. It + was done in the loader as a debugging aid and not intended as a + service/feature. +0.3: Pass the physical address of the bootinfo block in register r8 + to the kernel. Continue to put it at the fixed address for now. +0.2: Much improved version. Significant is the support for passing + the FPSWA interface pointer to the kernel. +0.1: Initial EFI version, germinated from the NetBSD i386 + standalone, but enormously modified. diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile index d4c2f6d3b1..ee2459501b 100644 --- a/sys/boot/ficl/Makefile +++ b/sys/boot/ficl/Makefile @@ -1,39 +1,64 @@ -# $FreeBSD: src/sys/boot/ficl/Makefile,v 1.17.2.6 2002/07/19 18:46:28 ru Exp $ -# $DragonFly: src/sys/boot/ficl/Makefile,v 1.2 2003/06/17 04:28:17 dillon Exp $ +# $FreeBSD: src/sys/boot/ficl/Makefile,v 1.35 2003/06/30 19:08:49 ru Exp $ +# $DragonFly: src/sys/boot/ficl/Makefile,v 1.3 2003/11/10 06:08:33 dillon Exp $ # -.PATH: ${.CURDIR}/${MACHINE_ARCH} -BASE_SRCS= dict.c ficl.c math64.c stack.c vm.c words.c -SRCS= ${BASE_SRCS} sysdep.c softcore.c -CLEANFILES= softcore.c testmain testmain.o +.if ${MACHINE_ARCH} == "amd64" +.MAKEFLAGS: MACHINE_ARCH=i386 MACHINE=i386 REALLY_AMD64=true +.endif + +.PATH: ${.CURDIR}/${MACHINE_ARCH} +BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ + prefix.c search.c stack.c tools.c vm.c words.c + +SRCS= ${BASE_SRCS} sysdep.c softcore.c +CLEANFILES= softcore.c testmain testmain.o +CFLAGS+= -ffreestanding .if ${MACHINE_ARCH} == "alpha" -CFLAGS+= -mno-fp-regs +CFLAGS+= -mno-fp-regs .endif .if ${MACHINE_ARCH} == "i386" -CFLAGS+= -mpreferred-stack-boundary=2 +CFLAGS+= -mpreferred-stack-boundary=2 +.endif +.if ${MACHINE} == "pc98" +CFLAGS+= -DPC98 +.endif +.if HAVE_PNP +CFLAGS+= -DHAVE_PNP .endif .ifmake testmain -CFLAGS+= -DTESTMAIN -D_TESTMAIN -SRCS+= testmain.c -PROG= testmain +CFLAGS+= -DTESTMAIN -D_TESTMAIN +SRCS+= testmain.c +PROG= testmain .include .else -LIB= ficl -INTERNALLIB= yes -SRCS+= loader.c +LIB= ficl +INTERNALLIB= yes .include .endif # Standard softwords +.PATH: ${.CURDIR}/softwords SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \ ifbrack.fr # Optional OO extension softwords #SOFTWORDS+= oo.fr classes.fr -.PATH: ${.CURDIR}/softwords -CFLAGS+= -I${.CURDIR} -I${.CURDIR}/${MACHINE_ARCH} -I${.CURDIR}/../common -DFICL_TRACE +.if defined(REALLY_AMD64) +CFLAGS+= -m32 -I. +.endif + +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/${MACHINE_ARCH} -I${.CURDIR}/../common -softcore.c: ${SOFTWORDS} softcore.awk +softcore.c: ${SOFTWORDS} softcore.awk (cd ${.CURDIR}/softwords; cat ${SOFTWORDS} \ | awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET} +.if defined(REALLY_AMD64) +${SRCS:M*.c:R:S/$/.o/g}: machine + +beforedepend ${OBJS}: machine +machine: + ln -sf ${.CURDIR}/../../i386/include machine + +CLEANFILES+= machine +.endif diff --git a/sys/boot/ficl/alpha/sysdep.c b/sys/boot/ficl/alpha/sysdep.c index 4d4d6a010e..84e0522164 100644 --- a/sys/boot/ficl/alpha/sysdep.c +++ b/sys/boot/ficl/alpha/sysdep.c @@ -7,8 +7,10 @@ ** *******************************************************************/ -/* $FreeBSD: src/sys/boot/ficl/alpha/sysdep.c,v 1.7.2.1 2000/07/06 23:51:46 obrien Exp $ */ -/* $DragonFly: src/sys/boot/ficl/alpha/Attic/sysdep.c,v 1.2 2003/06/17 04:28:18 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/alpha/sysdep.c,v 1.8 2000/06/02 20:07:55 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/alpha/Attic/sysdep.c,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #ifdef TESTMAIN #include diff --git a/sys/boot/ficl/alpha/sysdep.h b/sys/boot/ficl/alpha/sysdep.h index 5fef14d6e0..fac88eaf6a 100644 --- a/sys/boot/ficl/alpha/sysdep.h +++ b/sys/boot/ficl/alpha/sysdep.h @@ -9,31 +9,47 @@ ** FICL_ROBUST is enabled. This may require some consideration ** in firmware systems since assert often ** assumes stderr/stdout. -** +** $Id: sysdep.h,v 1.11 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ /* -** N O T I C E -- DISCLAIMER OF WARRANTY -** -** Ficl is freeware. Use it in any way that you like, with -** the understanding that the code is not supported. -** -** Any third party may reproduce, distribute, or modify the ficl -** software code or any derivative works thereof without any -** compensation or license, provided that the author information -** and this disclaimer text are retained in the source code files. -** The ficl software code is provided on an "as is" basis without -** warranty of any kind, including, without limitation, the implied -** warranties of merchantability and fitness for a particular purpose -** and their equivalents under the laws of any jurisdiction. -** +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** ** I am interested in hearing from anyone who uses ficl. If you have ** a problem, a success story, a defect, an enhancement request, or -** if you would like to contribute to the ficl release (yay!), please -** send me email at the address above. +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ -/* $FreeBSD: src/sys/boot/ficl/alpha/sysdep.h,v 1.5.2.1 2000/07/06 23:51:46 obrien Exp $ */ -/* $DragonFly: src/sys/boot/ficl/alpha/Attic/sysdep.h,v 1.2 2003/06/17 04:28:18 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/alpha/sysdep.h,v 1.9 2002/05/16 21:21:50 trhodes Exp $ + * $DragonFly: src/sys/boot/ficl/alpha/Attic/sysdep.h,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #if !defined (__SYSDEP_H__) #define __SYSDEP_H__ @@ -42,14 +58,12 @@ #include /* size_t, NULL */ #include - #include #if !defined IGNORE /* Macro to silence unused param warnings */ #define IGNORE(x) &x #endif - /* ** TRUE and FALSE for C boolean operations, and ** portable 32 bit types for CELLs @@ -62,7 +76,6 @@ #define FALSE 0 #endif - /* ** System dependent data type declarations... */ @@ -90,6 +103,7 @@ ** FICL_UNS and FICL_INT must have the same size as a void* on ** the target system. A CELL is a union of void*, FICL_UNS, and ** FICL_INT. +** (11/2000: same for FICL_FLOAT) */ #if !defined FICL_INT #define FICL_INT long @@ -99,6 +113,10 @@ #define FICL_UNS unsigned long #endif +#if !defined FICL_FLOAT +#define FICL_FLOAT float +#endif + /* ** Ficl presently supports values of 32 and 64 for BITS_PER_CELL */ @@ -136,9 +154,128 @@ typedef struct /* -** Build controls +** B U I L D C O N T R O L S +*/ + +#if !defined (FICL_MINIMAL) +#define FICL_MINIMAL 0 +#endif +#if (FICL_MINIMAL) +#define FICL_WANT_SOFTWORDS 0 +#define FICL_WANT_FILE 0 +#define FICL_WANT_FLOAT 0 +#define FICL_WANT_USER 0 +#define FICL_WANT_LOCALS 0 +#define FICL_WANT_DEBUGGER 0 +#define FICL_WANT_OOP 0 +#define FICL_PLATFORM_EXTEND 0 +#define FICL_MULTITHREAD 0 +#define FICL_ROBUST 0 +#define FICL_EXTENDED_PREFIX 0 +#endif + +/* +** FICL_PLATFORM_EXTEND +** Includes words defined in ficlCompilePlatform +*/ +#if !defined (FICL_PLATFORM_EXTEND) +#define FICL_PLATFORM_EXTEND 1 +#endif + + +/* +** FICL_WANT_FILE +** Includes the FILE and FILE-EXT wordset and associated code. Turn this off if you do not +** have a filesystem! +** Contributed by Larry Hastings +*/ +#if !defined (FICL_WANT_FILE) +#define FICL_WANT_FILE 0 +#endif + +/* +** FICL_WANT_FLOAT +** Includes a floating point stack for the VM, and words to do float operations. +** Contributed by Guy Carver +*/ +#if !defined (FICL_WANT_FLOAT) +#define FICL_WANT_FLOAT 0 +#endif + +/* +** FICL_WANT_DEBUGGER +** Inludes a simple source level debugger +*/ +#if !defined (FICL_WANT_DEBUGGER) +#define FICL_WANT_DEBUGGER 1 +#endif + +/* +** FICL_EXTENDED_PREFIX enables a bunch of extra prefixes in prefix.c and prefix.fr (if +** included as part of softcore.c) +*/ +#if !defined FICL_EXTENDED_PREFIX +#define FICL_EXTENDED_PREFIX 0 +#endif + +/* +** User variables: per-instance variables bound to the VM. +** Kinda like thread-local storage. Could be implemented in a +** VM private dictionary, but I've chosen the lower overhead +** approach of an array of CELLs instead. +*/ +#if !defined FICL_WANT_USER +#define FICL_WANT_USER 1 +#endif + +#if !defined FICL_USER_CELLS +#define FICL_USER_CELLS 16 +#endif + +/* +** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and +** a private dictionary for local variable compilation. +*/ +#if !defined FICL_WANT_LOCALS +#define FICL_WANT_LOCALS 1 +#endif + +/* Max number of local variables per definition */ +#if !defined FICL_MAX_LOCALS +#define FICL_MAX_LOCALS 16 +#endif + +/* +** FICL_WANT_OOP +** Inludes object oriented programming support (in softwords) +** OOP support requires locals and user variables! +*/ +#if !(FICL_WANT_LOCALS) || !(FICL_WANT_USER) +#if !defined (FICL_WANT_OOP) +#define FICL_WANT_OOP 0 +#endif +#endif + +#if !defined (FICL_WANT_OOP) +#define FICL_WANT_OOP 1 +#endif + +/* +** FICL_WANT_SOFTWORDS +** Controls inclusion of all softwords in softcore.c +*/ +#if !defined (FICL_WANT_SOFTWORDS) +#define FICL_WANT_SOFTWORDS 1 +#endif + +/* ** FICL_MULTITHREAD enables dictionary mutual exclusion ** wia the ficlLockDictionary system dependent function. +** Note: this implementation is experimental and poorly +** tested. Further, it's unnecessary unless you really +** intend to have multiple SESSIONS (poor choice of name +** on my part) - that is, threads that modify the dictionary +** at the same time. */ #if !defined FICL_MULTITHREAD #define FICL_MULTITHREAD 0 @@ -153,7 +290,6 @@ typedef struct #define PORTABLE_LONGMULDIV 0 #endif - /* ** INLINE_INNER_LOOP causes the inner interpreter to be inline code ** instead of a function call. This is mainly because MS VC++ 5 @@ -215,30 +351,13 @@ typedef struct #endif /* -** User variables: per-instance variables bound to the VM. -** Kinda like thread-local storage. Could be implemented in a -** VM private dictionary, but I've chosen the lower overhead -** approach of an array of CELLs instead. +** FICL_MAX_PARSE_STEPS controls the size of an array in the FICL_SYSTEM structure +** that stores pointers to parser extension functions. I would never expect to have +** more than 8 of these, so that's the default limit. Too many of these functions +** will probably exact a nasty performance penalty. */ -#if !defined FICL_WANT_USER -#define FICL_WANT_USER 1 -#endif - -#if !defined FICL_USER_CELLS -#define FICL_USER_CELLS 16 -#endif - -/* -** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and -** a private dictionary for local variable compilation. -*/ -#if !defined FICL_WANT_LOCALS -#define FICL_WANT_LOCALS 1 -#endif - -/* Max number of local variables per definition */ -#if !defined FICL_MAX_LOCALS -#define FICL_MAX_LOCALS 16 +#if !defined FICL_MAX_PARSE_STEPS +#define FICL_MAX_PARSE_STEPS 8 #endif /* @@ -302,4 +421,15 @@ int ficlLockDictionary(short fLock); DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y); UNSQR ficlLongDiv(DPUNS q, FICL_UNS y); + +/* +** FICL_HAVE_FTRUNCATE indicates whether the current OS supports +** the ftruncate() function (available on most UNIXes). This +** function is necessary to provide the complete File-Access wordset. +*/ +#if !defined (FICL_HAVE_FTRUNCATE) +#define FICL_HAVE_FTRUNCATE 0 +#endif + + #endif /*__SYSDEP_H__*/ diff --git a/sys/boot/ficl/dict.c b/sys/boot/ficl/dict.c index 51a7a90f04..9427d01181 100644 --- a/sys/boot/ficl/dict.c +++ b/sys/boot/ficl/dict.c @@ -3,7 +3,7 @@ ** Forth Inspired Command Language - dictionary methods ** Author: John Sadler (john_sadler@alum.mit.edu) ** Created: 19 July 1997 -** +** $Id: dict.c,v 1.14 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ /* ** This file implements the dictionary -- FICL's model of @@ -16,13 +16,48 @@ ** ** 29 jun 1998 (sadler) added variable sized hash table support */ +/* +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** +** I am interested in hearing from anyone who uses ficl. If you have +** a problem, a success story, a defect, an enhancement request, or +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +*/ -/* $FreeBSD: src/sys/boot/ficl/dict.c,v 1.6.2.1 2000/07/06 23:51:45 obrien Exp $ */ -/* $DragonFly: src/sys/boot/ficl/dict.c,v 1.2 2003/06/17 04:28:17 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/dict.c,v 1.13 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/dict.c,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #ifdef TESTMAIN #include -#include #include #else #include @@ -31,8 +66,8 @@ #include "ficl.h" /* Dictionary on-demand resizing control variables */ -unsigned int dictThreshold; -unsigned int dictIncrease; +CELL dictThreshold; +CELL dictIncrease; static char *dictCopyName(FICL_DICT *pDict, STRINGINFO si); @@ -269,16 +304,19 @@ int dictCellsUsed(FICL_DICT *pDict) /************************************************************************** d i c t C h e c k ** Checks the dictionary for corruption and throws appropriate -** errors +** errors. +** Input: +n number of ADDRESS UNITS (not Cells) proposed to allot +** -n number of ADDRESS UNITS proposed to de-allot +** 0 just do a consistency check **************************************************************************/ void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int n) { - if ((n >= 0) && (dictCellsAvail(pDict) * sizeof (CELL) < n)) + if ((n >= 0) && (dictCellsAvail(pDict) * (int)sizeof(CELL) < n)) { vmThrowErr(pVM, "Error: dictionary full"); } - if ((n <= 0) && (dictCellsUsed(pDict) * sizeof (CELL) < -n)) + if ((n <= 0) && (dictCellsUsed(pDict) * (int)sizeof(CELL) < -n)) { vmThrowErr(pVM, "Error: dictionary underflow"); } @@ -361,12 +399,32 @@ FICL_DICT *dictCreateHashed(unsigned nCells, unsigned nHash) memset(pDict, 0, sizeof (FICL_DICT)); pDict->dict = ficlMalloc(nAlloc); assert(pDict->dict); + pDict->size = nCells; dictEmpty(pDict, nHash); return pDict; } +/************************************************************************** + d i c t C r e a t e W o r d l i s t +** Create and initialize an anonymous wordlist +**************************************************************************/ +FICL_HASH *dictCreateWordlist(FICL_DICT *dp, int nBuckets) +{ + FICL_HASH *pHash; + + dictAlign(dp); + pHash = (FICL_HASH *)dp->here; + dictAllot(dp, sizeof (FICL_HASH) + + (nBuckets-1) * sizeof (FICL_WORD *)); + + pHash->size = nBuckets; + hashReset(pHash); + return pHash; +} + + /************************************************************************** d i c t D e l e t e ** Free all memory allocated for the given dictionary @@ -405,6 +463,84 @@ void dictEmpty(FICL_DICT *pDict, unsigned nHash) } +/************************************************************************** + d i c t H a s h S u m m a r y +** Calculate a figure of merit for the dictionary hash table based +** on the average search depth for all the words in the dictionary, +** assuming uniform distribution of target keys. The figure of merit +** is the ratio of the total search depth for all keys in the table +** versus a theoretical optimum that would be achieved if the keys +** were distributed into the table as evenly as possible. +** The figure would be worse if the hash table used an open +** addressing scheme (i.e. collisions resolved by searching the +** table for an empty slot) for a given size table. +**************************************************************************/ +#if FICL_WANT_FLOAT +void dictHashSummary(FICL_VM *pVM) +{ + FICL_DICT *dp = vmGetDict(pVM); + FICL_HASH *pFHash; + FICL_WORD **pHash; + unsigned size; + FICL_WORD *pFW; + unsigned i; + int nMax = 0; + int nWords = 0; + int nFilled; + double avg = 0.0; + double best; + int nAvg, nRem, nDepth; + + dictCheck(dp, pVM, 0); + + pFHash = dp->pSearch[dp->nLists - 1]; + pHash = pFHash->table; + size = pFHash->size; + nFilled = size; + + for (i = 0; i < size; i++) + { + int n = 0; + pFW = pHash[i]; + + while (pFW) + { + ++n; + ++nWords; + pFW = pFW->link; + } + + avg += (double)(n * (n+1)) / 2.0; + + if (n > nMax) + nMax = n; + if (n == 0) + --nFilled; + } + + /* Calc actual avg search depth for this hash */ + avg = avg / nWords; + + /* Calc best possible performance with this size hash */ + nAvg = nWords / size; + nRem = nWords % size; + nDepth = size * (nAvg * (nAvg+1))/2 + (nAvg+1)*nRem; + best = (double)nDepth/nWords; + + sprintf(pVM->pad, + "%d bins, %2.0f%% filled, Depth: Max=%d, Avg=%2.1f, Best=%2.1f, Score: %2.0f%%", + size, + (double)nFilled * 100.0 / size, nMax, + avg, + best, + 100.0 * best / avg); + + ficlTextOut(pVM, pVM->pad, 1); + + return; +} +#endif + /************************************************************************** d i c t I n c l u d e s ** Returns TRUE iff the given pointer is within the address range of @@ -417,7 +553,6 @@ int dictIncludes(FICL_DICT *pDict, void *p) ); } - /************************************************************************** d i c t L o o k u p ** Find the FICL_WORD that matches the given name and length. @@ -447,15 +582,16 @@ FICL_WORD *dictLookup(FICL_DICT *pDict, STRINGINFO si) /************************************************************************** - d i c t L o o k u p L o c + f i c l L o o k u p L o c ** Same as dictLookup, but looks in system locals dictionary first... ** Assumes locals dictionary has only one wordlist... **************************************************************************/ #if FICL_WANT_LOCALS -FICL_WORD *dictLookupLoc(FICL_DICT *pDict, STRINGINFO si) +FICL_WORD *ficlLookupLoc(FICL_SYSTEM *pSys, STRINGINFO si) { FICL_WORD *pFW = NULL; - FICL_HASH *pHash = ficlGetLoc()->pForthWords; + FICL_DICT *pDict = pSys->dp; + FICL_HASH *pHash = ficlGetLoc(pSys)->pForthWords; int i; UNS16 hashCode = hashHashCode(si); @@ -607,7 +743,8 @@ UNS16 hashHashCode(STRINGINFO si) if (si.count == 0) return 0; - for (cp = (UNS8 *)si.cp; *cp && si.count; cp++, si.count--) + /* changed to run without errors under Purify -- lch */ + for (cp = (UNS8 *)si.cp; si.count && *cp; cp++, si.count--) { code = (UNS16)((code << 4) + tolower(*cp)); shift = (UNS16)(code & 0xf000); @@ -622,6 +759,8 @@ UNS16 hashHashCode(STRINGINFO si) } + + /************************************************************************** h a s h I n s e r t W o r d ** Put a word into the hash table using the word's hashcode as @@ -660,7 +799,7 @@ void hashInsertWord(FICL_HASH *pHash, FICL_WORD *pFW) **************************************************************************/ FICL_WORD *hashLookup(FICL_HASH *pHash, STRINGINFO si, UNS16 hashCode) { - FICL_COUNT nCmp = (FICL_COUNT)si.count; + FICL_UNS nCmp = si.count; FICL_WORD *pFW; UNS16 hashIdx; @@ -705,6 +844,7 @@ void hashReset(FICL_HASH *pHash) } pHash->link = NULL; + pHash->name = NULL; return; } @@ -716,11 +856,12 @@ void hashReset(FICL_HASH *pHash) void dictCheckThreshold(FICL_DICT* dp) { - if( dictCellsAvail(dp) < dictThreshold ) { - dp->dict = ficlMalloc( dictIncrease * sizeof (CELL) ); + if( dictCellsAvail(dp) < dictThreshold.u ) { + dp->dict = ficlMalloc( dictIncrease.u * sizeof (CELL) ); assert(dp->dict); dp->here = dp->dict; - dp->size = dictIncrease; + dp->size = dictIncrease.u; + dictAlign(dp); } } diff --git a/sys/boot/ficl/ficl.c b/sys/boot/ficl/ficl.c index 40b6559111..ba059a0262 100644 --- a/sys/boot/ficl/ficl.c +++ b/sys/boot/ficl/ficl.c @@ -3,7 +3,7 @@ ** Forth Inspired Command Language - external interface ** Author: John Sadler (john_sadler@alum.mit.edu) ** Created: 19 July 1997 -** +** $Id: ficl.c,v 1.16 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ /* ** This is an ANS Forth interpreter written in C. @@ -15,14 +15,50 @@ ** interpreter is re-entrant, so it can be used in multiple instances ** in a multitasking system. Unlike Forth, Ficl's outer interpreter ** expects a text block as input, and returns to the caller after each -** text block, so the data pump is somewhere in external code. This -** is more like TCL than Forth. +** text block, so the data pump is somewhere in external code in the +** style of TCL. ** ** Code is written in ANSI C for portability. */ +/* +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** +** I am interested in hearing from anyone who uses ficl. If you have +** a problem, a success story, a defect, an enhancement request, or +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +*/ -/* $FreeBSD: src/sys/boot/ficl/ficl.c,v 1.13.2.1 2000/07/06 23:51:45 obrien Exp $ */ -/* $DragonFly: src/sys/boot/ficl/ficl.c,v 1.2 2003/06/17 04:28:17 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/ficl.c,v 1.18 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/ficl.c,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #ifdef TESTMAIN #include @@ -32,36 +68,22 @@ #include #include "ficl.h" -#ifdef FICL_TRACE -int ficl_trace = 0; -#endif - - -/* -** Local prototypes -*/ - /* ** System statics -** The system builds a global dictionary during its start -** sequence. This is shared by all interpreter instances. -** Therefore only one instance can update the dictionary +** Each FICL_SYSTEM builds a global dictionary during its start +** sequence. This is shared by all virtual machines of that system. +** Therefore only one VM can update the dictionary ** at a time. The system imports a locking function that ** you can override in order to control update access to ** the dictionary. The function is stubbed out by default, ** but you can insert one: #define FICL_MULTITHREAD 1 ** and supply your own version of ficlLockDictionary. */ -static FICL_DICT *dp = NULL; -static FICL_DICT *envp = NULL; -#if FICL_WANT_LOCALS -static FICL_DICT *localp = NULL; -#endif -static FICL_VM *vmList = NULL; - static int defaultStack = FICL_DEFAULT_STACK; -static int defaultDict = FICL_DEFAULT_DICT; + + +static void ficlSetVersionEnv(FICL_SYSTEM *pSys); /************************************************************************** @@ -75,37 +97,154 @@ static int defaultDict = FICL_DEFAULT_DICT; ** precompiled part. Try 1K cells minimum. Use "words" to find ** out how much of the dictionary is used at any time. **************************************************************************/ -void ficlInitSystem(int nDictCells) +FICL_SYSTEM *ficlInitSystemEx(FICL_SYSTEM_INFO *fsi) { - if (dp) - dictDelete(dp); + int nDictCells; + int nEnvCells; + FICL_SYSTEM *pSys = ficlMalloc(sizeof (FICL_SYSTEM)); - if (envp) - dictDelete(envp); + assert(pSys); + assert(fsi->size == sizeof (FICL_SYSTEM_INFO)); -#if FICL_WANT_LOCALS - if (localp) - dictDelete(localp); -#endif + memset(pSys, 0, sizeof (FICL_SYSTEM)); + nDictCells = fsi->nDictCells; if (nDictCells <= 0) - nDictCells = defaultDict; + nDictCells = FICL_DEFAULT_DICT; + + nEnvCells = fsi->nEnvCells; + if (nEnvCells <= 0) + nEnvCells = FICL_DEFAULT_DICT; + + pSys->dp = dictCreateHashed((unsigned)nDictCells, HASHSIZE); + pSys->dp->pForthWords->name = "forth-wordlist"; + + pSys->envp = dictCreate((unsigned)nEnvCells); + pSys->envp->pForthWords->name = "environment"; + + pSys->textOut = fsi->textOut; + pSys->pExtend = fsi->pExtend; - dp = dictCreateHashed((unsigned)nDictCells, HASHSIZE); - envp = dictCreate( (unsigned)FICL_DEFAULT_ENV); #if FICL_WANT_LOCALS /* ** The locals dictionary is only searched while compiling, ** but this is where speed is most important. On the other ** hand, the dictionary gets emptied after each use of locals - ** The need to balance search speed with the cost of the empty + ** The need to balance search speed with the cost of the 'empty' ** operation led me to select a single-threaded list... */ - localp = dictCreate( (unsigned)FICL_MAX_LOCALS * CELLS_PER_WORD); + pSys->localp = dictCreate((unsigned)FICL_MAX_LOCALS * CELLS_PER_WORD); +#endif + + /* + ** Build the precompiled dictionary and load softwords. We need a temporary + ** VM to do this - ficlNewVM links one to the head of the system VM list. + ** ficlCompilePlatform (defined in win32.c, for example) adds platform specific words. + */ + ficlCompileCore(pSys); + ficlCompilePrefix(pSys); +#if FICL_WANT_FLOAT + ficlCompileFloat(pSys); +#endif +#if FICL_PLATFORM_EXTEND + ficlCompilePlatform(pSys); +#endif + ficlSetVersionEnv(pSys); + + /* + ** Establish the parse order. Note that prefixes precede numbers - + ** this allows constructs like "0b101010" which might parse as a + ** hex value otherwise. + */ + ficlAddPrecompiledParseStep(pSys, "?prefix", ficlParsePrefix); + ficlAddPrecompiledParseStep(pSys, "?number", ficlParseNumber); +#if FICL_WANT_FLOAT + ficlAddPrecompiledParseStep(pSys, ">float", ficlParseFloatNumber); #endif - ficlCompileCore(dp); + /* + ** Now create a temporary VM to compile the softwords. Since all VMs are + ** linked into the vmList of FICL_SYSTEM, we don't have to pass the VM + ** to ficlCompileSoftCore -- it just hijacks whatever it finds in the VM list. + ** ficl 2.05: vmCreate no longer depends on the presence of INTERPRET in the + ** dictionary, so a VM can be created before the dictionary is built. It just + ** can't do much... + */ + ficlNewVM(pSys); + ficlCompileSoftCore(pSys); + ficlFreeVM(pSys->vmList); + + + return pSys; +} + + +FICL_SYSTEM *ficlInitSystem(int nDictCells) +{ + FICL_SYSTEM_INFO fsi; + ficlInitInfo(&fsi); + fsi.nDictCells = nDictCells; + return ficlInitSystemEx(&fsi); +} + +/************************************************************************** + f i c l A d d P a r s e S t e p +** Appends a parse step function to the end of the parse list (see +** FICL_PARSE_STEP notes in ficl.h for details). Returns 0 if successful, +** nonzero if there's no more room in the list. +**************************************************************************/ +int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW) +{ + int i; + for (i = 0; i < FICL_MAX_PARSE_STEPS; i++) + { + if (pSys->parseList[i] == NULL) + { + pSys->parseList[i] = pFW; + return 0; + } + } + + return 1; +} + + +/* +** Compile a word into the dictionary that invokes the specified FICL_PARSE_STEP +** function. It is up to the user (as usual in Forth) to make sure the stack +** preconditions are valid (there needs to be a counted string on top of the stack) +** before using the resulting word. +*/ +void ficlAddPrecompiledParseStep(FICL_SYSTEM *pSys, char *name, FICL_PARSE_STEP pStep) +{ + FICL_DICT *dp = pSys->dp; + FICL_WORD *pFW = dictAppendWord(dp, name, parseStepParen, FW_DEFAULT); + dictAppendCell(dp, LVALUEtoCELL(pStep)); + ficlAddParseStep(pSys, pFW); +} + + +/* +** This word lists the parse steps in order +*/ +void ficlListParseSteps(FICL_VM *pVM) +{ + int i; + FICL_SYSTEM *pSys = pVM->pSys; + assert(pSys); + + vmTextOut(pVM, "Parse steps:", 1); + vmTextOut(pVM, "lookup", 1); + + for (i = 0; i < FICL_MAX_PARSE_STEPS; i++) + { + if (pSys->parseList[i] != NULL) + { + vmTextOut(pVM, pSys->parseList[i]->name, 1); + } + else break; + } return; } @@ -113,21 +252,17 @@ void ficlInitSystem(int nDictCells) /************************************************************************** f i c l N e w V M ** Create a new virtual machine and link it into the system list -** of VMs for later cleanup by ficlTermSystem. If this is the first -** VM to be created, use it to compile the words in softcore.c +** of VMs for later cleanup by ficlTermSystem. **************************************************************************/ -FICL_VM *ficlNewVM(void) +FICL_VM *ficlNewVM(FICL_SYSTEM *pSys) { FICL_VM *pVM = vmCreate(NULL, defaultStack, defaultStack); - pVM->link = vmList; + pVM->link = pSys->vmList; + pVM->pSys = pSys; + pVM->pExtend = pSys->pExtend; + vmSetTextOut(pVM, pSys->textOut); - /* - ** Borrow the first vm to build the soft words in softcore.c - */ - if (vmList == NULL) - ficlCompileSoftCore(pVM); - - vmList = pVM; + pSys->vmList = pVM; return pVM; } @@ -141,26 +276,27 @@ FICL_VM *ficlNewVM(void) **************************************************************************/ void ficlFreeVM(FICL_VM *pVM) { - FICL_VM *pList = vmList; - - assert(pVM != 0); - - if (vmList == pVM) - { - vmList = vmList->link; - } - else for (pList; pList != 0; pList = pList->link) - { - if (pList->link == pVM) - { - pList->link = pVM->link; - break; - } - } - - if (pList) - vmDelete(pVM); - return; + FICL_SYSTEM *pSys = pVM->pSys; + FICL_VM *pList = pSys->vmList; + + assert(pVM != 0); + + if (pSys->vmList == pVM) + { + pSys->vmList = pSys->vmList->link; + } + else for (; pList != NULL; pList = pList->link) + { + if (pList->link == pVM) + { + pList->link = pVM->link; + break; + } + } + + if (pList) + vmDelete(pVM); + return; } @@ -179,16 +315,33 @@ void ficlFreeVM(FICL_VM *pVM) ** flags -- 0 or more of F_IMMEDIATE, F_COMPILE, use bitwise OR! ** **************************************************************************/ -int ficlBuild(char *name, FICL_CODE code, char flags) +int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code, char flags) { - int err = ficlLockDictionary(TRUE); - if (err) return err; +#if FICL_MULTITHREAD + int err = ficlLockDictionary(TRUE); + if (err) return err; +#endif /* FICL_MULTITHREAD */ - assert(dictCellsAvail(dp) > sizeof (FICL_WORD) / sizeof (CELL)); - dictAppendWord(dp, name, code, flags); + assert(dictCellsAvail(pSys->dp) > sizeof (FICL_WORD) / sizeof (CELL)); + dictAppendWord(pSys->dp, name, code, flags); - ficlLockDictionary(FALSE); - return 0; + ficlLockDictionary(FALSE); + return 0; +} + + +/************************************************************************** + f i c l E v a l u a t e +** Wrapper for ficlExec() which sets SOURCE-ID to -1. +**************************************************************************/ +int ficlEvaluate(FICL_VM *pVM, char *pText) +{ + int returnValue; + CELL id = pVM->sourceID; + pVM->sourceID.i = -1; + returnValue = ficlExecC(pVM, pText, -1); + pVM->sourceID = id; + return returnValue; } @@ -217,18 +370,16 @@ int ficlExec(FICL_VM *pVM, char *pText) int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size) { - static FICL_WORD *pInterp = NULL; + FICL_SYSTEM *pSys = pVM->pSys; + FICL_DICT *dp = pSys->dp; int except; jmp_buf vmState; jmp_buf *oldState; TIB saveTib; - if (!pInterp) - pInterp = ficlLookup("interpret"); - - assert(pInterp); assert(pVM); + assert(pSys->pInterp[0]); if (size < 0) size = strlen(pText); @@ -247,12 +398,12 @@ int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size) case 0: if (pVM->fRestart) { - pVM->fRestart = 0; pVM->runningWord->code(pVM); + pVM->fRestart = 0; } else { /* set VM up to interpret text */ - vmPushIP(pVM, &pInterp); + vmPushIP(pVM, &(pSys->pInterp[0])); } vmInnerLoop(pVM); @@ -273,6 +424,7 @@ int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size) case VM_USEREXIT: case VM_INNEREXIT: + case VM_BREAK: break; case VM_QUIT: @@ -280,7 +432,7 @@ int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size) { dictAbortDefinition(dp); #if FICL_WANT_LOCALS - dictEmpty(localp, localp->pForthWords->size); + dictEmpty(pSys->localp, pSys->localp->pForthWords->size); #endif } vmQuit(pVM); @@ -294,7 +446,7 @@ int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size) { dictAbortDefinition(dp); #if FICL_WANT_LOCALS - dictEmpty(localp, localp->pForthWords->size); + dictEmpty(pSys->localp, pSys->localp->pForthWords->size); #endif } dictResetSearchOrder(dp); @@ -307,53 +459,6 @@ int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size) return (except); } -/************************************************************************** - f i c l E x e c F D -** reads in text from file fd and passes it to ficlExec() - * returns VM_OUTOFTEXT on success or the ficlExec() error code on - * failure. - */ -#define nLINEBUF 256 -int ficlExecFD(FICL_VM *pVM, int fd) -{ - char cp[nLINEBUF]; - int nLine = 0, rval = VM_OUTOFTEXT; - char ch; - CELL id; - - id = pVM->sourceID; - pVM->sourceID.i = fd; - - /* feed each line to ficlExec */ - while (1) { - int status, i; - - i = 0; - while ((status = read(fd, &ch, 1)) > 0 && ch != '\n') - cp[i++] = ch; - nLine++; - if (!i) { - if (status < 1) - break; - continue; - } - rval = ficlExecC(pVM, cp, i); - if(rval != VM_QUIT && rval != VM_USEREXIT && rval != VM_OUTOFTEXT) - { - pVM->sourceID = id; - return rval; - } - } - /* - ** Pass an empty line with SOURCE-ID == -1 to flush - ** any pending REFILLs (as required by FILE wordset) - */ - pVM->sourceID.i = -1; - ficlExec(pVM, ""); - - pVM->sourceID = id; - return rval; -} /************************************************************************** f i c l E x e c X T @@ -374,17 +479,19 @@ int ficlExecFD(FICL_VM *pVM, int fd) **************************************************************************/ int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord) { - static FICL_WORD *pQuit = NULL; int except; jmp_buf vmState; jmp_buf *oldState; - - if (!pQuit) - pQuit = ficlLookup("exit-inner"); + FICL_WORD *oldRunningWord; assert(pVM); - assert(pQuit); + assert(pVM->pSys->pExitInner); + /* + ** Save the runningword so that RESTART behaves correctly + ** over nested calls. + */ + oldRunningWord = pVM->runningWord; /* ** Save and restore VM's jmp_buf to enable nested calls */ @@ -395,7 +502,7 @@ int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord) if (except) vmPopIP(pVM); else - vmPushIP(pVM, &pQuit); + vmPushIP(pVM, &(pVM->pSys->pExitInner)); switch (except) { @@ -405,6 +512,7 @@ int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord) break; case VM_INNEREXIT: + case VM_BREAK: break; case VM_RESTART: @@ -424,6 +532,7 @@ int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord) } pVM->pState = oldState; + pVM->runningWord = oldRunningWord; return (except); } @@ -434,11 +543,11 @@ int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord) ** found, return the address of the corresponding FICL_WORD. Otherwise ** return NULL. **************************************************************************/ -FICL_WORD *ficlLookup(char *name) +FICL_WORD *ficlLookup(FICL_SYSTEM *pSys, char *name) { STRINGINFO si; SI_PSZ(si, name); - return dictLookup(dp, si); + return dictLookup(pSys->dp, si); } @@ -446,9 +555,9 @@ FICL_WORD *ficlLookup(char *name) f i c l G e t D i c t ** Returns the address of the system dictionary **************************************************************************/ -FICL_DICT *ficlGetDict(void) +FICL_DICT *ficlGetDict(FICL_SYSTEM *pSys) { - return dp; + return pSys->dp; } @@ -456,9 +565,9 @@ FICL_DICT *ficlGetDict(void) f i c l G e t E n v ** Returns the address of the system environment space **************************************************************************/ -FICL_DICT *ficlGetEnv(void) +FICL_DICT *ficlGetEnv(FICL_SYSTEM *pSys) { - return envp; + return pSys->envp; } @@ -467,10 +576,11 @@ FICL_DICT *ficlGetEnv(void) ** Create an environment variable with a one-CELL payload. ficlSetEnvD ** makes one with a two-CELL payload. **************************************************************************/ -void ficlSetEnv(char *name, FICL_UNS value) +void ficlSetEnv(FICL_SYSTEM *pSys, char *name, FICL_UNS value) { STRINGINFO si; FICL_WORD *pFW; + FICL_DICT *envp = pSys->envp; SI_PSZ(si, name); pFW = dictLookup(envp, si); @@ -488,10 +598,11 @@ void ficlSetEnv(char *name, FICL_UNS value) return; } -void ficlSetEnvD(char *name, FICL_UNS hi, FICL_UNS lo) +void ficlSetEnvD(FICL_SYSTEM *pSys, char *name, FICL_UNS hi, FICL_UNS lo) { FICL_WORD *pFW; STRINGINFO si; + FICL_DICT *envp = pSys->envp; SI_PSZ(si, name); pFW = dictLookup(envp, si); @@ -517,9 +628,9 @@ void ficlSetEnvD(char *name, FICL_UNS hi, FICL_UNS lo) ** only used during compilation, and is shared by all VMs. **************************************************************************/ #if FICL_WANT_LOCALS -FICL_DICT *ficlGetLoc(void) +FICL_DICT *ficlGetLoc(FICL_SYSTEM *pSys) { - return localp; + return pSys->localp; } #endif @@ -546,30 +657,43 @@ int ficlSetStackSize(int nStackCells) ** Tear the system down by deleting the dictionaries and all VMs. ** This saves you from having to keep track of all that stuff. **************************************************************************/ -void ficlTermSystem(void) +void ficlTermSystem(FICL_SYSTEM *pSys) { - if (dp) - dictDelete(dp); - dp = NULL; + if (pSys->dp) + dictDelete(pSys->dp); + pSys->dp = NULL; - if (envp) - dictDelete(envp); - envp = NULL; + if (pSys->envp) + dictDelete(pSys->envp); + pSys->envp = NULL; #if FICL_WANT_LOCALS - if (localp) - dictDelete(localp); - localp = NULL; + if (pSys->localp) + dictDelete(pSys->localp); + pSys->localp = NULL; #endif - while (vmList != NULL) + while (pSys->vmList != NULL) { - FICL_VM *pVM = vmList; - vmList = vmList->link; + FICL_VM *pVM = pSys->vmList; + pSys->vmList = pSys->vmList->link; vmDelete(pVM); } + ficlFree(pSys); + pSys = NULL; return; } +/************************************************************************** + f i c l S e t V e r s i o n E n v +** Create a double cell environment constant for the version ID +**************************************************************************/ +static void ficlSetVersionEnv(FICL_SYSTEM *pSys) +{ + ficlSetEnvD(pSys, "ficl-version", FICL_VER_MAJOR, FICL_VER_MINOR); + ficlSetEnv (pSys, "ficl-robust", FICL_ROBUST); + return; +} + diff --git a/sys/boot/ficl/ficl.h b/sys/boot/ficl/ficl.h index caff6cf70a..c12c046212 100644 --- a/sys/boot/ficl/ficl.h +++ b/sys/boot/ficl/ficl.h @@ -3,32 +3,48 @@ ** Forth Inspired Command Language ** Author: John Sadler (john_sadler@alum.mit.edu) ** Created: 19 July 1997 -** +** Dedicated to RHS, in loving memory +** $Id: ficl.h,v 1.18 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ /* -** N O T I C E -- DISCLAIMER OF WARRANTY -** -** Ficl is freeware. Use it in any way that you like, with -** the understanding that the code is supported on a "best effort" -** basis only. -** -** Any third party may reproduce, distribute, or modify the ficl -** software code or any derivative works thereof without any -** compensation or license, provided that the author information -** and this disclaimer text are retained in the source code files. -** The ficl software code is provided on an "as is" basis without -** warranty of any kind, including, without limitation, the implied -** warranties of merchantability and fitness for a particular purpose -** and their equivalents under the laws of any jurisdiction. -** +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** ** I am interested in hearing from anyone who uses ficl. If you have ** a problem, a success story, a defect, an enhancement request, or -** if you would like to contribute to the ficl release (yay!), please -** send me email at the address above. +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ -/* $FreeBSD: src/sys/boot/ficl/ficl.h,v 1.11.2.1 2000/07/06 23:44:58 obrien Exp $ */ -/* $DragonFly: src/sys/boot/ficl/ficl.h,v 1.2 2003/06/17 04:28:17 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/ficl.h,v 1.20 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/ficl.h,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #if !defined (__FICL_H__) #define __FICL_H__ @@ -111,17 +127,14 @@ ** T o D o L i s t ** ** 1. Unimplemented system dependent CORE word: key -** 2. Kludged CORE word: ACCEPT -** 3. Dictionary locking is full of holes - only one vm at a time -** can alter the dict. -** 4. Ficl uses the pad in CORE words - this violates the standard, +** 2. Ficl uses the PAD in some CORE words - this violates the standard, ** but it's cleaner for a multithreaded system. I'll have to make a ** second pad for reference by the word PAD to fix this. ** ** F o r M o r e I n f o r m a t i o n ** ** Web home of ficl -** http://www.taygeta.com/forth/compilers +** http://ficl.sourceforge.net ** Check this website for Forth literature (including the ANSI standard) ** http://www.taygeta.com/forthlit.html ** and here for software and more links @@ -140,7 +153,7 @@ ** - Make the main hash table a bigger prime (HASHSIZE) ** - FORGET about twiddling the hash function - my experience is ** that that is a waste of time. -** - eliminate the need to pass the pVM parameter on the stack +** - Eliminate the need to pass the pVM parameter on the stack ** by dedicating a register to it. Most words need access to the ** vm, but the parameter passing overhead can be reduced. One way ** requires that the host OS have a task switch callout. Create @@ -214,13 +227,22 @@ extern "C" { ** Forward declarations... read on. */ struct ficl_word; +typedef struct ficl_word FICL_WORD; struct vm; +typedef struct vm FICL_VM; struct ficl_dict; +typedef struct ficl_dict FICL_DICT; +struct ficl_system; +typedef struct ficl_system FICL_SYSTEM; +struct ficl_system_info; +typedef struct ficl_system_info FICL_SYSTEM_INFO; /* ** the Good Stuff starts here... */ -#define FICL_VER "2.03" +#define FICL_VER "3.02" +#define FICL_VER_MAJOR 3 +#define FICL_VER_MINOR 2 #if !defined (FICL_PROMPT) #define FICL_PROMPT "ok> " #endif @@ -230,7 +252,7 @@ struct ficl_dict; ** complement of false... that unifies logical and bitwise operations ** nicely. */ -#define FICL_TRUE (~(0L)) +#define FICL_TRUE ((unsigned long)~(0L)) #define FICL_FALSE (0) #define FICL_BOOL(x) ((x) ? FICL_TRUE : FICL_FALSE) @@ -238,17 +260,22 @@ struct ficl_dict; /* ** A CELL is the main storage type. It must be large enough ** to contain a pointer or a scalar. In order to accommodate -** 32 bit and 64 bit processors, use abstract types for i and u. +** 32 bit and 64 bit processors, use abstract types for int, +** unsigned, and float. */ typedef union _cell { - FICL_INT i; + FICL_INT i; FICL_UNS u; - void *p; +#if (FICL_WANT_FLOAT) + FICL_FLOAT f; +#endif + void *p; + void (*fn)(void); } CELL; /* -** LVALUEtoCELL does a little pointer trickery to cast any 32 bit +** LVALUEtoCELL does a little pointer trickery to cast any CELL sized ** lvalue (informal definition: an expression whose result has an ** address) to CELL. Remember that constants and casts are NOT ** themselves lvalues! @@ -302,7 +329,7 @@ typedef struct {si.cp = pfs->text; si.count = pfs->count;} /* -** Ficl uses a this little structure to hold the address of +** Ficl uses this little structure to hold the address of ** the block of text it's working on and an index to the next ** unconsumed character in the string. Traditionally, this is ** done by a Text Input Buffer, so I've called this struct TIB. @@ -337,33 +364,65 @@ typedef struct _ficlStack FICL_UNS nCells; /* size of the stack */ CELL *pFrame; /* link reg for stack frame */ CELL *sp; /* stack pointer */ - CELL base[1]; /* Bottom of the stack */ + CELL base[1]; /* Top of stack */ } FICL_STACK; /* ** Stack methods... many map closely to required Forth words. */ -FICL_STACK *stackCreate(unsigned nCells); -void stackDelete(FICL_STACK *pStack); -int stackDepth (FICL_STACK *pStack); -void stackDrop (FICL_STACK *pStack, int n); -CELL stackFetch (FICL_STACK *pStack, int n); -CELL stackGetTop(FICL_STACK *pStack); -void stackLink (FICL_STACK *pStack, int nCells); -void stackPick (FICL_STACK *pStack, int n); -CELL stackPop (FICL_STACK *pStack); +FICL_STACK *stackCreate (unsigned nCells); +void stackDelete (FICL_STACK *pStack); +int stackDepth (FICL_STACK *pStack); +void stackDrop (FICL_STACK *pStack, int n); +CELL stackFetch (FICL_STACK *pStack, int n); +CELL stackGetTop (FICL_STACK *pStack); +void stackLink (FICL_STACK *pStack, int nCells); +void stackPick (FICL_STACK *pStack, int n); +CELL stackPop (FICL_STACK *pStack); void *stackPopPtr (FICL_STACK *pStack); -FICL_UNS stackPopUNS(FICL_STACK *pStack); -FICL_INT stackPopINT(FICL_STACK *pStack); -void stackPush (FICL_STACK *pStack, CELL c); +FICL_UNS stackPopUNS (FICL_STACK *pStack); +FICL_INT stackPopINT (FICL_STACK *pStack); +void stackPush (FICL_STACK *pStack, CELL c); void stackPushPtr (FICL_STACK *pStack, void *ptr); -void stackPushUNS(FICL_STACK *pStack, FICL_UNS u); -void stackPushINT(FICL_STACK *pStack, FICL_INT i); -void stackReset (FICL_STACK *pStack); -void stackRoll (FICL_STACK *pStack, int n); -void stackSetTop(FICL_STACK *pStack, CELL c); -void stackStore (FICL_STACK *pStack, int n, CELL c); -void stackUnlink(FICL_STACK *pStack); +void stackPushUNS (FICL_STACK *pStack, FICL_UNS u); +void stackPushINT (FICL_STACK *pStack, FICL_INT i); +void stackReset (FICL_STACK *pStack); +void stackRoll (FICL_STACK *pStack, int n); +void stackSetTop (FICL_STACK *pStack, CELL c); +void stackStore (FICL_STACK *pStack, int n, CELL c); +void stackUnlink (FICL_STACK *pStack); + +#if (FICL_WANT_FLOAT) +float stackPopFloat (FICL_STACK *pStack); +void stackPushFloat(FICL_STACK *pStack, FICL_FLOAT f); +#endif + +/* +** Shortcuts (Guy Carver) +*/ +#define PUSHPTR(p) stackPushPtr(pVM->pStack,p) +#define PUSHUNS(u) stackPushUNS(pVM->pStack,u) +#define PUSHINT(i) stackPushINT(pVM->pStack,i) +#define PUSHFLOAT(f) stackPushFloat(pVM->fStack,f) +#define PUSH(c) stackPush(pVM->pStack,c) +#define POPPTR() stackPopPtr(pVM->pStack) +#define POPUNS() stackPopUNS(pVM->pStack) +#define POPINT() stackPopINT(pVM->pStack) +#define POPFLOAT() stackPopFloat(pVM->fStack) +#define POP() stackPop(pVM->pStack) +#define GETTOP() stackGetTop(pVM->pStack) +#define SETTOP(c) stackSetTop(pVM->pStack,LVALUEtoCELL(c)) +#define GETTOPF() stackGetTop(pVM->fStack) +#define SETTOPF(c) stackSetTop(pVM->fStack,LVALUEtoCELL(c)) +#define STORE(n,c) stackStore(pVM->pStack,n,LVALUEtoCELL(c)) +#define DEPTH() stackDepth(pVM->pStack) +#define DROP(n) stackDrop(pVM->pStack,n) +#define DROPF(n) stackDrop(pVM->fStack,n) +#define FETCH(n) stackFetch(pVM->pStack,n) +#define PICK(n) stackPick(pVM->pStack,n) +#define PICKF(n) stackPick(pVM->fStack,n) +#define ROLL(n) stackRoll(pVM->pStack,n) +#define ROLLF(n) stackRoll(pVM->fStack,n) /* ** The virtual machine (VM) contains the state for one interpreter. @@ -377,7 +436,7 @@ void stackUnlink(FICL_STACK *pStack); ** Throw an exception */ -typedef struct ficl_word ** IPTYPE; /* the VM's instruction pointer */ +typedef FICL_WORD ** IPTYPE; /* the VM's instruction pointer */ /* ** Each VM has a placeholder for an output function - @@ -385,7 +444,7 @@ typedef struct ficl_word ** IPTYPE; /* the VM's instruction pointer */ ** through a different device. If you specify no ** OUTFUNC, it defaults to ficlTextOut. */ -typedef void (*OUTFUNC)(struct vm *pVM, char *text, int fNewline); +typedef void (*OUTFUNC)(FICL_VM *pVM, char *text, int fNewline); /* ** Each VM operates in one of two non-error states: interpreting @@ -410,33 +469,36 @@ typedef void (*OUTFUNC)(struct vm *pVM, char *text, int fNewline); ** ANS Forth requires that a word's name contain {1..31} characters. */ #if !defined nFICLNAME -#define nFICLNAME 31 +#define nFICLNAME 31 #endif /* ** OK - now we can really define the VM... */ -typedef struct vm +struct vm { - struct vm *link; /* Ficl keeps a VM list for simple teardown */ + FICL_SYSTEM *pSys; /* Which system this VM belongs to */ + FICL_VM *link; /* Ficl keeps a VM list for simple teardown */ jmp_buf *pState; /* crude exception mechanism... */ OUTFUNC textOut; /* Output callback - see sysdep.c */ - void * pExtend; /* vm extension pointer */ + void * pExtend; /* vm extension pointer for app use - initialized from FICL_SYSTEM */ short fRestart; /* Set TRUE to restart runningWord */ IPTYPE ip; /* instruction pointer */ - struct ficl_word - *runningWord;/* address of currently running word (often just *(ip-1) ) */ + FICL_WORD *runningWord;/* address of currently running word (often just *(ip-1) ) */ FICL_UNS state; /* compiling or interpreting */ FICL_UNS base; /* number conversion base */ FICL_STACK *pStack; /* param stack */ FICL_STACK *rStack; /* return stack */ - CELL sourceID; /* -1 if string, 0 if normal input */ +#if FICL_WANT_FLOAT + FICL_STACK *fStack; /* float stack (optional) */ +#endif + CELL sourceID; /* -1 if EVALUATE, 0 if normal input */ TIB tib; /* address of incoming text string */ #if FICL_WANT_USER CELL user[FICL_USER_CELLS]; #endif char pad[nPAD]; /* the scratch area (see above) */ -} FICL_VM; +}; /* ** A FICL_CODE points to a function that gets called to help execute @@ -462,10 +524,10 @@ typedef void (*FICL_CODE)(FICL_VM *pVm); ** words in a linked list called the dictionary. ** A FICL_WORD starts each entry in the list. ** Version 1.02: space for the name characters is allotted from -** the dictionary ahead of the word struct - this saves about half -** the storage on average with very little runtime cost. +** the dictionary ahead of the word struct, rather than using +** a fixed size array for each name. */ -typedef struct ficl_word +struct ficl_word { struct ficl_word *link; /* Previous word in the dictionary */ UNS16 hash; @@ -474,7 +536,7 @@ typedef struct ficl_word char *name; /* First nFICLNAME chars of word name */ FICL_CODE code; /* Native code to execute the word */ CELL param[1]; /* First data cell of the word */ -} FICL_WORD; +}; /* ** Worst-case size of a word header: nFICLNAME chars in name @@ -490,7 +552,7 @@ int wordIsCompileOnly(FICL_WORD *pFW); #define FW_IMMEDIATE 1 /* execute me even if compiling */ #define FW_COMPILE 2 /* error if executed when not compiling */ #define FW_SMUDGE 4 /* definition in progress - hide me */ -#define FW_CLASS 8 /* Word defines a class */ +#define FW_ISOBJECT 8 /* word is an object or object member variable */ #define FW_COMPIMMED (FW_IMMEDIATE | FW_COMPILE) #define FW_DEFAULT 0 @@ -504,34 +566,34 @@ int wordIsCompileOnly(FICL_WORD *pFW); #define VM_RESTART -258 /* word needs more text to succeed - re-run it */ #define VM_USEREXIT -259 /* user wants to quit */ #define VM_ERREXIT -260 /* interp found an error */ +#define VM_BREAK -261 /* debugger breakpoint */ #define VM_ABORT -1 /* like errexit -- abort */ #define VM_ABORTQ -2 /* like errexit -- abort" */ #define VM_QUIT -56 /* like errexit, but leave pStack & base alone */ void vmBranchRelative(FICL_VM *pVM, int offset); -FICL_VM * vmCreate (FICL_VM *pVM, unsigned nPStack, unsigned nRStack); -void vmDelete (FICL_VM *pVM); -void vmExecute(FICL_VM *pVM, FICL_WORD *pWord); -char * vmGetString(FICL_VM *pVM, FICL_STRING *spDest, char delimiter); -STRINGINFO vmGetWord(FICL_VM *pVM); -STRINGINFO vmGetWord0(FICL_VM *pVM); -int vmGetWordToPad(FICL_VM *pVM); -STRINGINFO vmParseString(FICL_VM *pVM, char delimiter); +FICL_VM * vmCreate (FICL_VM *pVM, unsigned nPStack, unsigned nRStack); +void vmDelete (FICL_VM *pVM); +void vmExecute (FICL_VM *pVM, FICL_WORD *pWord); +FICL_DICT *vmGetDict (FICL_VM *pVM); +char * vmGetString (FICL_VM *pVM, FICL_STRING *spDest, char delimiter); +STRINGINFO vmGetWord (FICL_VM *pVM); +STRINGINFO vmGetWord0 (FICL_VM *pVM); +int vmGetWordToPad (FICL_VM *pVM); +STRINGINFO vmParseString (FICL_VM *pVM, char delimiter); STRINGINFO vmParseStringEx(FICL_VM *pVM, char delimiter, char fSkipLeading); -CELL vmPop(FICL_VM *pVM); -void vmPush(FICL_VM *pVM, CELL c); -void vmPopIP (FICL_VM *pVM); -void vmPushIP (FICL_VM *pVM, IPTYPE newIP); -void vmQuit (FICL_VM *pVM); -void vmReset (FICL_VM *pVM); -void vmSetTextOut(FICL_VM *pVM, OUTFUNC textOut); -#if FICL_WANT_DEBUGGER -void vmStep(FICL_VM *pVM); -#endif -void vmTextOut(FICL_VM *pVM, char *text, int fNewline); -void vmThrow (FICL_VM *pVM, int except); -void vmThrowErr(FICL_VM *pVM, char *fmt, ...); +CELL vmPop (FICL_VM *pVM); +void vmPush (FICL_VM *pVM, CELL c); +void vmPopIP (FICL_VM *pVM); +void vmPushIP (FICL_VM *pVM, IPTYPE newIP); +void vmQuit (FICL_VM *pVM); +void vmReset (FICL_VM *pVM); +void vmSetTextOut (FICL_VM *pVM, OUTFUNC textOut); +void vmTextOut (FICL_VM *pVM, char *text, int fNewline); +void vmTextOut (FICL_VM *pVM, char *text, int fNewline); +void vmThrow (FICL_VM *pVM, int except); +void vmThrowErr (FICL_VM *pVM, char *fmt, ...); #define vmGetRunningWord(pVM) ((pVM)->runningWord) @@ -543,7 +605,7 @@ void vmThrowErr(FICL_VM *pVM, char *fmt, ...); #define M_VM_STEP(pVM) \ FICL_WORD *tempFW = *(pVM)->ip++; \ (pVM)->runningWord = tempFW; \ - tempFW->code(pVM); \ + tempFW->code(pVM); #define M_INNER_LOOP(pVM) \ for (;;) { M_VM_STEP(pVM) } @@ -562,6 +624,9 @@ void vmInnerLoop(FICL_VM *pVM); ** a word's stack effect comment. */ void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells); +#if FICL_WANT_FLOAT +void vmCheckFStack(FICL_VM *pVM, int popCells, int pushCells); +#endif /* ** TIB access routines... @@ -573,11 +638,12 @@ void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells); ** PopTib restores the TIB state given a saved TIB from PushTib ** GetInBuf returns a pointer to the next unused char of the TIB */ -void vmPushTib(FICL_VM *pVM, char *text, FICL_INT nChars, TIB *pSaveTib); -void vmPopTib(FICL_VM *pVM, TIB *pTib); -#define vmGetInBuf(pVM) ((pVM)->tib.cp + (pVM)->tib.index) -#define vmGetInBufLen(pVM) ((pVM)->tib.end - (pVM)->tib.cp) -#define vmGetInBufEnd(pVM) ((pVM)->tib.end) +void vmPushTib (FICL_VM *pVM, char *text, FICL_INT nChars, TIB *pSaveTib); +void vmPopTib (FICL_VM *pVM, TIB *pTib); +#define vmGetInBuf(pVM) ((pVM)->tib.cp + (pVM)->tib.index) +#define vmGetInBufLen(pVM) ((pVM)->tib.end - (pVM)->tib.cp) +#define vmGetInBufEnd(pVM) ((pVM)->tib.end) +#define vmGetTibIndex(pVM) (pVM)->tib.index #define vmSetTibIndex(pVM, i) (pVM)->tib.index = i #define vmUpdateTib(pVM, str) (pVM)->tib.index = (str) - (pVM)->tib.cp @@ -601,7 +667,7 @@ char digit_to_char(int value); char *strrev( char *string ); char *skipSpace(char *cp, char *end); char *caseFold(char *cp); -int strincmp(char *cp1, char *cp2, FICL_COUNT count); +int strincmp(char *cp1, char *cp2, FICL_UNS count); #if defined(_WIN32) && !FICL_MAIN #pragma warning(default: 4273) @@ -615,23 +681,22 @@ int strincmp(char *cp1, char *cp2, FICL_COUNT count); ** just a pointer to a FICL_HASH in this implementation. */ #if !defined HASHSIZE /* Default size of hash table. For most uniform */ -#define HASHSIZE 127 /* performance, use a prime number! */ +#define HASHSIZE 241 /* performance, use a prime number! */ #endif typedef struct ficl_hash { - struct ficl_hash *link; /* eventual inheritance support */ - unsigned size; + struct ficl_hash *link; /* link to parent class wordlist for OO */ + char *name; /* optional pointer to \0 terminated wordlist name */ + unsigned size; /* number of buckets in the hash */ FICL_WORD *table[1]; } FICL_HASH; -void hashForget(FICL_HASH *pHash, void *where); -UNS16 hashHashCode(STRINGINFO si); +void hashForget (FICL_HASH *pHash, void *where); +UNS16 hashHashCode (STRINGINFO si); void hashInsertWord(FICL_HASH *pHash, FICL_WORD *pFW); -FICL_WORD *hashLookup(struct ficl_hash *pHash, - STRINGINFO si, - UNS16 hashCode); -void hashReset(FICL_HASH *pHash); +FICL_WORD *hashLookup (FICL_HASH *pHash, STRINGINFO si, UNS16 hashCode); +void hashReset (FICL_HASH *pHash); /* ** A Dictionary is a linked list of FICL_WORDs. It is also Ficl's @@ -664,7 +729,7 @@ void hashReset(FICL_HASH *pHash); ** size -- number of cells in the dictionary (total) ** dict -- start of data area. Must be at the end of the struct. */ -typedef struct ficl_dict +struct ficl_dict { CELL *here; FICL_WORD *smudge; @@ -674,16 +739,16 @@ typedef struct ficl_dict int nLists; unsigned size; /* Number of cells in dict (total)*/ CELL *dict; /* Base of dictionary memory */ -} FICL_DICT; +}; void *alignPtr(void *ptr); void dictAbortDefinition(FICL_DICT *pDict); -void dictAlign(FICL_DICT *pDict); -int dictAllot(FICL_DICT *pDict, int n); -int dictAllotCells(FICL_DICT *pDict, int nCells); -void dictAppendCell(FICL_DICT *pDict, CELL c); -void dictAppendChar(FICL_DICT *pDict, char c); -FICL_WORD *dictAppendWord(FICL_DICT *pDict, +void dictAlign (FICL_DICT *pDict); +int dictAllot (FICL_DICT *pDict, int n); +int dictAllotCells (FICL_DICT *pDict, int nCells); +void dictAppendCell (FICL_DICT *pDict, CELL c); +void dictAppendChar (FICL_DICT *pDict, char c); +FICL_WORD *dictAppendWord (FICL_DICT *pDict, char *name, FICL_CODE pCode, UNS8 flags); @@ -691,25 +756,152 @@ FICL_WORD *dictAppendWord2(FICL_DICT *pDict, STRINGINFO si, FICL_CODE pCode, UNS8 flags); -void dictAppendUNS(FICL_DICT *pDict, FICL_UNS u); -int dictCellsAvail(FICL_DICT *pDict); -int dictCellsUsed (FICL_DICT *pDict); -void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int nCells); +void dictAppendUNS (FICL_DICT *pDict, FICL_UNS u); +int dictCellsAvail (FICL_DICT *pDict); +int dictCellsUsed (FICL_DICT *pDict); +void dictCheck (FICL_DICT *pDict, FICL_VM *pVM, int n); FICL_DICT *dictCreate(unsigned nCELLS); FICL_DICT *dictCreateHashed(unsigned nCells, unsigned nHash); -void dictDelete(FICL_DICT *pDict); -void dictEmpty(FICL_DICT *pDict, unsigned nHash); -int dictIncludes(FICL_DICT *pDict, void *p); -FICL_WORD *dictLookup(FICL_DICT *pDict, STRINGINFO si); +FICL_HASH *dictCreateWordlist(FICL_DICT *dp, int nBuckets); +void dictDelete (FICL_DICT *pDict); +void dictEmpty (FICL_DICT *pDict, unsigned nHash); +#if FICL_WANT_FLOAT +void dictHashSummary(FICL_VM *pVM); +#endif +int dictIncludes (FICL_DICT *pDict, void *p); +FICL_WORD *dictLookup (FICL_DICT *pDict, STRINGINFO si); #if FICL_WANT_LOCALS -FICL_WORD *dictLookupLoc(FICL_DICT *pDict, STRINGINFO si); +FICL_WORD *ficlLookupLoc (FICL_SYSTEM *pSys, STRINGINFO si); #endif void dictResetSearchOrder(FICL_DICT *pDict); -void dictSetFlags(FICL_DICT *pDict, UNS8 set, UNS8 clr); +void dictSetFlags (FICL_DICT *pDict, UNS8 set, UNS8 clr); void dictSetImmediate(FICL_DICT *pDict); -void dictUnsmudge(FICL_DICT *pDict); -CELL *dictWhere(FICL_DICT *pDict); +void dictUnsmudge (FICL_DICT *pDict); +CELL *dictWhere (FICL_DICT *pDict); + + +/* +** P A R S E S T E P +** (New for 2.05) +** See words.c: interpWord +** By default, ficl goes through two attempts to parse each token from its input +** stream: it first attempts to match it with a word in the dictionary, and +** if that fails, it attempts to convert it into a number. This mechanism is now +** extensible by additional steps. This allows extensions like floating point and +** double number support to be factored cleanly. +** +** Each parse step is a function that receives the next input token as a STRINGINFO. +** If the parse step matches the token, it must apply semantics to the token appropriate +** to the present value of VM.state (compiling or interpreting), and return FICL_TRUE. +** Otherwise it returns FICL_FALSE. See words.c: isNumber for an example +** +** Note: for the sake of efficiency, it's a good idea both to limit the number +** of parse steps and to code each parse step so that it rejects tokens that +** do not match as quickly as possible. +*/ + +typedef int (*FICL_PARSE_STEP)(FICL_VM *pVM, STRINGINFO si); + +/* +** Appends a parse step function to the end of the parse list (see +** FICL_PARSE_STEP notes in ficl.h for details). Returns 0 if successful, +** nonzero if there's no more room in the list. Each parse step is a word in +** the dictionary. Precompiled parse steps can use (PARSE-STEP) as their +** CFA - see parenParseStep in words.c. +*/ +int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW); /* ficl.c */ +void ficlAddPrecompiledParseStep(FICL_SYSTEM *pSys, char *name, FICL_PARSE_STEP pStep); +void ficlListParseSteps(FICL_VM *pVM); + +/* +** FICL_BREAKPOINT record. +** origXT - if NULL, this breakpoint is unused. Otherwise it stores the xt +** that the breakpoint overwrote. This is restored to the dictionary when the +** BP executes or gets cleared +** address - the location of the breakpoint (address of the instruction that +** has been replaced with the breakpoint trap +** origXT - The original contents of the location with the breakpoint +** Note: address is NULL when this breakpoint is empty +*/ +typedef struct FICL_BREAKPOINT +{ + void *address; + FICL_WORD *origXT; +} FICL_BREAKPOINT; + + +/* +** F I C L _ S Y S T E M +** The top level data structure of the system - ficl_system ties a list of +** virtual machines with their corresponding dictionaries. Ficl 3.0 will +** support multiple Ficl systems, allowing multiple concurrent sessions +** to separate dictionaries with some constraints. +** The present model allows multiple sessions to one dictionary provided +** you implement ficlLockDictionary() as specified in sysdep.h +** Note: the pExtend pointer is there to provide context for applications. It is copied +** to each VM's pExtend field as that VM is created. +*/ +struct ficl_system +{ + FICL_SYSTEM *link; + void *pExtend; /* Initializes VM's pExtend pointer (for application use) */ + FICL_VM *vmList; + FICL_DICT *dp; + FICL_DICT *envp; +#ifdef FICL_WANT_LOCALS + FICL_DICT *localp; +#endif + FICL_WORD *pInterp[3]; + FICL_WORD *parseList[FICL_MAX_PARSE_STEPS]; + OUTFUNC textOut; + + FICL_WORD *pBranchParen; + FICL_WORD *pDoParen; + FICL_WORD *pDoesParen; + FICL_WORD *pExitInner; + FICL_WORD *pExitParen; + FICL_WORD *pIfParen; + FICL_WORD *pInterpret; + FICL_WORD *pLitParen; + FICL_WORD *pTwoLitParen; + FICL_WORD *pLoopParen; + FICL_WORD *pPLoopParen; + FICL_WORD *pQDoParen; + FICL_WORD *pSemiParen; + FICL_WORD *pStore; + FICL_WORD *pCStringLit; + FICL_WORD *pStringLit; + +#if FICL_WANT_LOCALS + FICL_WORD *pGetLocalParen; + FICL_WORD *pGet2LocalParen; + FICL_WORD *pGetLocal0; + FICL_WORD *pGetLocal1; + FICL_WORD *pToLocalParen; + FICL_WORD *pTo2LocalParen; + FICL_WORD *pToLocal0; + FICL_WORD *pToLocal1; + FICL_WORD *pLinkParen; + FICL_WORD *pUnLinkParen; + FICL_INT nLocals; + CELL *pMarkLocals; +#endif + + FICL_BREAKPOINT bpStep; +}; + +struct ficl_system_info +{ + int size; /* structure size tag for versioning */ + int nDictCells; /* Size of system's Dictionary */ + OUTFUNC textOut; /* default textOut function */ + void *pExtend; /* Initializes VM's pExtend pointer - for application use */ + int nEnvCells; /* Size of Environment dictionary */ +}; + +#define ficlInitInfo(x) { memset((x), 0, sizeof(FICL_SYSTEM_INFO)); \ + (x)->size = sizeof(FICL_SYSTEM_INFO); } /* ** External interface to FICL... @@ -718,7 +910,8 @@ CELL *dictWhere(FICL_DICT *pDict); ** f i c l I n i t S y s t e m ** Binds a global dictionary to the interpreter system and initializes ** the dict to contain the ANSI CORE wordset. -** You specify the address and size of the allocated area. +** You can specify the address and size of the allocated area. +** Using ficlInitSystemEx you can also specify the text output function. ** After that, ficl manages it. ** First step is to set up the static pointers to the area. ** Then write the "precompiled" portion of the dictionary in. @@ -726,7 +919,10 @@ CELL *dictWhere(FICL_DICT *pDict); ** precompiled part. Try 1K cells minimum. Use "words" to find ** out how much of the dictionary is used at any time. */ -void ficlInitSystem(int nDictCells); +FICL_SYSTEM *ficlInitSystemEx(FICL_SYSTEM_INFO *fsi); + +/* Deprecated call */ +FICL_SYSTEM *ficlInitSystem(int nDictCells); /* ** f i c l T e r m S y s t e m @@ -734,7 +930,17 @@ void ficlInitSystem(int nDictCells); ** were created with ficlNewVM (see below). Call this function to ** reclaim all memory used by the dictionary and VMs. */ -void ficlTermSystem(void); +void ficlTermSystem(FICL_SYSTEM *pSys); + +/* +** f i c l E v a l u a t e +** Evaluates a block of input text in the context of the +** specified interpreter. Also sets SOURCE-ID properly. +** +** PLEASE USE THIS FUNCTION when throwing a hard-coded +** string to the FICL interpreter. +*/ +int ficlEvaluate(FICL_VM *pVM, char *pText); /* ** f i c l E x e c @@ -757,6 +963,10 @@ void ficlTermSystem(void); ** commands. ** Preconditions: successful execution of ficlInitSystem, ** Successful creation and init of the VM by ficlNewVM (or equiv) +** +** If you call ficlExec() or one of its brothers, you MUST +** ensure pVM->sourceID was set to a sensible value. +** ficlExec() explicitly DOES NOT manage SOURCE-ID for you. */ int ficlExec (FICL_VM *pVM, char *pText); int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT nChars); @@ -776,7 +986,7 @@ int ficlExecFD(FICL_VM *pVM, int fd); ** address of the VM, or NULL if an error occurs. ** Precondition: successful execution of ficlInitSystem */ -FICL_VM *ficlNewVM(void); +FICL_VM *ficlNewVM(FICL_SYSTEM *pSys); /* ** Force deletion of a VM. You do not need to do this @@ -799,19 +1009,19 @@ int ficlSetStackSize(int nStackCells); ** dictionary with the given name, or NULL if no match. ** Precondition: successful execution of ficlInitSystem */ -FICL_WORD *ficlLookup(char *name); +FICL_WORD *ficlLookup(FICL_SYSTEM *pSys, char *name); /* ** f i c l G e t D i c t ** Utility function - returns the address of the system dictionary. ** Precondition: successful execution of ficlInitSystem */ -FICL_DICT *ficlGetDict(void); -FICL_DICT *ficlGetEnv(void); -void ficlSetEnv(char *name, FICL_UNS value); -void ficlSetEnvD(char *name, FICL_UNS hi, FICL_UNS lo); +FICL_DICT *ficlGetDict(FICL_SYSTEM *pSys); +FICL_DICT *ficlGetEnv (FICL_SYSTEM *pSys); +void ficlSetEnv (FICL_SYSTEM *pSys, char *name, FICL_UNS value); +void ficlSetEnvD(FICL_SYSTEM *pSys, char *name, FICL_UNS hi, FICL_UNS lo); #if FICL_WANT_LOCALS -FICL_DICT *ficlGetLoc(void); +FICL_DICT *ficlGetLoc (FICL_SYSTEM *pSys); #endif /* ** f i c l B u i l d @@ -829,34 +1039,74 @@ FICL_DICT *ficlGetLoc(void); ** Most words can use FW_DEFAULT. ** nAllot - number of extra cells to allocate in the parameter area (usually zero) */ -int ficlBuild(char *name, FICL_CODE code, char flags); +int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code, char flags); /* ** f i c l C o m p i l e C o r e ** Builds the ANS CORE wordset into the dictionary - called by ** ficlInitSystem - no need to waste dict space by doing it again. */ -void ficlCompileCore(FICL_DICT *dp); -void ficlCompileSoftCore(FICL_VM *pVM); +void ficlCompileCore(FICL_SYSTEM *pSys); +void ficlCompilePrefix(FICL_SYSTEM *pSys); +void ficlCompileSearch(FICL_SYSTEM *pSys); +void ficlCompileSoftCore(FICL_SYSTEM *pSys); +void ficlCompileTools(FICL_SYSTEM *pSys); +void ficlCompileFile(FICL_SYSTEM *pSys); +#if FICL_WANT_FLOAT +void ficlCompileFloat(FICL_SYSTEM *pSys); +int ficlParseFloatNumber( FICL_VM *pVM, STRINGINFO si ); /* float.c */ +#endif +#if FICL_PLATFORM_EXTEND +void ficlCompilePlatform(FICL_SYSTEM *pSys); +#endif +int ficlParsePrefix(FICL_VM *pVM, STRINGINFO si); /* ** from words.c... */ void constantParen(FICL_VM *pVM); void twoConstParen(FICL_VM *pVM); +int ficlParseNumber(FICL_VM *pVM, STRINGINFO si); +void ficlTick(FICL_VM *pVM); +void parseStepParen(FICL_VM *pVM); /* -** Dictionary on-demand resizing +** From tools.c */ -extern unsigned int dictThreshold; -extern unsigned int dictIncrease; +int isAFiclWord(FICL_DICT *pd, FICL_WORD *pFW); -/* -** So we can more easily debug... +/* +** The following supports SEE and the debugger. */ -#ifdef FICL_TRACE -extern int ficl_trace; +typedef enum +{ + BRANCH, + COLON, + CONSTANT, + CREATE, + DO, + DOES, + IF, + LITERAL, + LOOP, + PLOOP, + PRIMITIVE, + QDO, + STRINGLIT, + CSTRINGLIT, +#if FICL_WANT_USER + USER, #endif + VARIABLE, +} WORDKIND; + +WORDKIND ficlWordClassify(FICL_WORD *pFW); + +/* +** Dictionary on-demand resizing +*/ +extern CELL dictThreshold; +extern CELL dictIncrease; /* ** Various FreeBSD goodies @@ -874,6 +1124,29 @@ extern void ficlGetenv(FICL_VM *pVM); extern void ficlUnsetenv(FICL_VM *pVM); extern void ficlCopyin(FICL_VM *pVM); extern void ficlCopyout(FICL_VM *pVM); +extern void ficlFindfile(FICL_VM *pVM); +extern void ficlPnpdevices(FICL_VM *pVM); +extern void ficlPnphandlers(FICL_VM *pVM); +extern void ficlCcall(FICL_VM *pVM); +#endif + +/* +** Used with File-Access wordset. +*/ +#define FICL_FAM_READ 1 +#define FICL_FAM_WRITE 2 +#define FICL_FAM_APPEND 4 +#define FICL_FAM_BINARY 8 + +#define FICL_FAM_OPEN_MODE(fam) ((fam) & (FICL_FAM_READ | FICL_FAM_WRITE | FICL_FAM_APPEND)) + + +#if (FICL_WANT_FILE) +typedef struct ficlFILE +{ + FILE *f; + char filename[256]; +} ficlFILE; #endif #ifdef __cplusplus diff --git a/sys/boot/ficl/fileaccess.c b/sys/boot/ficl/fileaccess.c new file mode 100644 index 0000000000..3135d059d2 --- /dev/null +++ b/sys/boot/ficl/fileaccess.c @@ -0,0 +1,428 @@ +/* + * $FreeBSD: src/sys/boot/ficl/fileaccess.c,v 1.1 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/fileaccess.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include "ficl.h" + +#if FICL_WANT_FILE +/* +** +** fileaccess.c +** +** Implements all of the File Access word set that can be implemented in portable C. +** +*/ + +static void pushIor(FICL_VM *pVM, int success) +{ + int ior; + if (success) + ior = 0; + else + ior = errno; + stackPushINT(pVM->pStack, ior); +} + + + +static void ficlFopen(FICL_VM *pVM, char *writeMode) /* ( c-addr u fam -- fileid ior ) */ +{ + int fam = stackPopINT(pVM->pStack); + int length = stackPopINT(pVM->pStack); + void *address = (void *)stackPopPtr(pVM->pStack); + char mode[4]; + FILE *f; + + char *filename = (char *)alloca(length + 1); + memcpy(filename, address, length); + filename[length] = 0; + + *mode = 0; + + switch (FICL_FAM_OPEN_MODE(fam)) + { + case 0: + stackPushPtr(pVM->pStack, NULL); + stackPushINT(pVM->pStack, EINVAL); + return; + case FICL_FAM_READ: + strcat(mode, "r"); + break; + case FICL_FAM_WRITE: + strcat(mode, writeMode); + break; + case FICL_FAM_READ | FICL_FAM_WRITE: + strcat(mode, writeMode); + strcat(mode, "+"); + break; + } + + strcat(mode, (fam & FICL_FAM_BINARY) ? "b" : "t"); + + f = fopen(filename, mode); + if (f == NULL) + stackPushPtr(pVM->pStack, NULL); + else + { + ficlFILE *ff = (ficlFILE *)malloc(sizeof(ficlFILE)); + strcpy(ff->filename, filename); + ff->f = f; + stackPushPtr(pVM->pStack, ff); + + fseek(f, 0, SEEK_SET); + } + pushIor(pVM, f != NULL); +} + + + +static void ficlOpenFile(FICL_VM *pVM) /* ( c-addr u fam -- fileid ior ) */ +{ + ficlFopen(pVM, "a"); +} + + +static void ficlCreateFile(FICL_VM *pVM) /* ( c-addr u fam -- fileid ior ) */ +{ + ficlFopen(pVM, "w"); +} + + +static int closeFiclFILE(ficlFILE *ff) /* ( fileid -- ior ) */ +{ + FILE *f = ff->f; + free(ff); + return !fclose(f); +} + +static void ficlCloseFile(FICL_VM *pVM) /* ( fileid -- ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + pushIor(pVM, closeFiclFILE(ff)); +} + +static void ficlDeleteFile(FICL_VM *pVM) /* ( c-addr u -- ior ) */ +{ + int length = stackPopINT(pVM->pStack); + void *address = (void *)stackPopPtr(pVM->pStack); + + char *filename = (char *)alloca(length + 1); + memcpy(filename, address, length); + filename[length] = 0; + + pushIor(pVM, !unlink(filename)); +} + +static void ficlRenameFile(FICL_VM *pVM) /* ( c-addr1 u1 c-addr2 u2 -- ior ) */ +{ + int length; + void *address; + char *from; + char *to; + + length = stackPopINT(pVM->pStack); + address = (void *)stackPopPtr(pVM->pStack); + to = (char *)alloca(length + 1); + memcpy(to, address, length); + to[length] = 0; + + length = stackPopINT(pVM->pStack); + address = (void *)stackPopPtr(pVM->pStack); + + from = (char *)alloca(length + 1); + memcpy(from, address, length); + from[length] = 0; + + pushIor(pVM, !rename(from, to)); +} + +static void ficlFileStatus(FICL_VM *pVM) /* ( c-addr u -- x ior ) */ +{ + struct stat statbuf; + + int length = stackPopINT(pVM->pStack); + void *address = (void *)stackPopPtr(pVM->pStack); + + char *filename = (char *)alloca(length + 1); + memcpy(filename, address, length); + filename[length] = 0; + + if (stat(filename, &statbuf) == 0) + { + /* + ** the "x" left on the stack is implementation-defined. + ** I push the file's access mode (readable, writeable, is directory, etc) + ** as defined by ANSI C. + */ + stackPushINT(pVM->pStack, statbuf.st_mode); + stackPushINT(pVM->pStack, 0); + } + else + { + stackPushINT(pVM->pStack, -1); + stackPushINT(pVM->pStack, ENOENT); + } +} + + +static void ficlFilePosition(FICL_VM *pVM) /* ( fileid -- ud ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + long ud = ftell(ff->f); + stackPushINT(pVM->pStack, ud); + pushIor(pVM, ud != -1); +} + + + +static long fileSize(FILE *f) +{ + struct stat statbuf; + statbuf.st_size = -1; + if (fstat(fileno(f), &statbuf) != 0) + return -1; + return statbuf.st_size; +} + + + +static void ficlFileSize(FICL_VM *pVM) /* ( fileid -- ud ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + long ud = fileSize(ff->f); + stackPushINT(pVM->pStack, ud); + pushIor(pVM, ud != -1); +} + + + +#define nLINEBUF 256 +static void ficlIncludeFile(FICL_VM *pVM) /* ( i*x fileid -- j*x ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + CELL id = pVM->sourceID; + int result = VM_OUTOFTEXT; + long currentPosition, totalSize; + long size; + pVM->sourceID.p = (void *)ff; + + currentPosition = ftell(ff->f); + totalSize = fileSize(ff->f); + size = totalSize - currentPosition; + + if ((totalSize != -1) && (currentPosition != -1) && (size > 0)) + { + char *buffer = (char *)malloc(size); + long got = fread(buffer, 1, size, ff->f); + if (got == size) + result = ficlExecC(pVM, buffer, size); + } + +#if 0 + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + CELL id = pVM->sourceID; + char cp[nLINEBUF]; + int nLine = 0; + int keepGoing; + int result; + pVM->sourceID.p = (void *)ff; + + /* feed each line to ficlExec */ + keepGoing = TRUE; + while (keepGoing && fgets(cp, nLINEBUF, ff->f)) + { + int len = strlen(cp) - 1; + + nLine++; + if (len <= 0) + continue; + + if (cp[len] == '\n') + cp[len] = '\0'; + + result = ficlExec(pVM, cp); + + switch (result) + { + case VM_OUTOFTEXT: + case VM_USEREXIT: + break; + + default: + pVM->sourceID = id; + keepGoing = FALSE; + break; + } + } +#endif /* 0 */ + /* + ** Pass an empty line with SOURCE-ID == -1 to flush + ** any pending REFILLs (as required by FILE wordset) + */ + pVM->sourceID.i = -1; + ficlExec(pVM, ""); + + pVM->sourceID = id; + closeFiclFILE(ff); +} + + + +static void ficlReadFile(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + int length = stackPopINT(pVM->pStack); + void *address = (void *)stackPopPtr(pVM->pStack); + int result; + + clearerr(ff->f); + result = fread(address, 1, length, ff->f); + + stackPushINT(pVM->pStack, result); + pushIor(pVM, ferror(ff->f) == 0); +} + + + +static void ficlReadLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 flag ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + int length = stackPopINT(pVM->pStack); + char *address = (char *)stackPopPtr(pVM->pStack); + int error; + int flag; + + if (feof(ff->f)) + { + stackPushINT(pVM->pStack, -1); + stackPushINT(pVM->pStack, 0); + stackPushINT(pVM->pStack, 0); + return; + } + + clearerr(ff->f); + *address = 0; + fgets(address, length, ff->f); + + error = ferror(ff->f); + if (error != 0) + { + stackPushINT(pVM->pStack, -1); + stackPushINT(pVM->pStack, 0); + stackPushINT(pVM->pStack, error); + return; + } + + length = strlen(address); + flag = (length > 0); + if (length && ((address[length - 1] == '\r') || (address[length - 1] == '\n'))) + length--; + + stackPushINT(pVM->pStack, length); + stackPushINT(pVM->pStack, flag); + stackPushINT(pVM->pStack, 0); /* ior */ +} + + + +static void ficlWriteFile(FICL_VM *pVM) /* ( c-addr u1 fileid -- ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + int length = stackPopINT(pVM->pStack); + void *address = (void *)stackPopPtr(pVM->pStack); + + clearerr(ff->f); + fwrite(address, 1, length, ff->f); + pushIor(pVM, ferror(ff->f) == 0); +} + + + +static void ficlWriteLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + size_t length = (size_t)stackPopINT(pVM->pStack); + void *address = (void *)stackPopPtr(pVM->pStack); + + clearerr(ff->f); + if (fwrite(address, 1, length, ff->f) == length) + fwrite("\n", 1, 1, ff->f); + pushIor(pVM, ferror(ff->f) == 0); +} + + + +static void ficlRepositionFile(FICL_VM *pVM) /* ( ud fileid -- ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + size_t ud = (size_t)stackPopINT(pVM->pStack); + + pushIor(pVM, fseek(ff->f, ud, SEEK_SET) == 0); +} + + + +static void ficlFlushFile(FICL_VM *pVM) /* ( fileid -- ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + pushIor(pVM, fflush(ff->f) == 0); +} + + + +#if FICL_HAVE_FTRUNCATE + +static void ficlResizeFile(FICL_VM *pVM) /* ( ud fileid -- ior ) */ +{ + ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); + size_t ud = (size_t)stackPopINT(pVM->pStack); + + pushIor(pVM, ftruncate(fileno(ff->f), ud) == 0); +} + +#endif /* FICL_HAVE_FTRUNCATE */ + +#endif /* FICL_WANT_FILE */ + + + +void ficlCompileFile(FICL_SYSTEM *pSys) +{ +#if FICL_WANT_FILE + FICL_DICT *dp = pSys->dp; + assert(dp); + + dictAppendWord(dp, "create-file", ficlCreateFile, FW_DEFAULT); + dictAppendWord(dp, "open-file", ficlOpenFile, FW_DEFAULT); + dictAppendWord(dp, "close-file", ficlCloseFile, FW_DEFAULT); + dictAppendWord(dp, "include-file", ficlIncludeFile, FW_DEFAULT); + dictAppendWord(dp, "read-file", ficlReadFile, FW_DEFAULT); + dictAppendWord(dp, "read-line", ficlReadLine, FW_DEFAULT); + dictAppendWord(dp, "write-file", ficlWriteFile, FW_DEFAULT); + dictAppendWord(dp, "write-line", ficlWriteLine, FW_DEFAULT); + dictAppendWord(dp, "file-position", ficlFilePosition, FW_DEFAULT); + dictAppendWord(dp, "file-size", ficlFileSize, FW_DEFAULT); + dictAppendWord(dp, "reposition-file", ficlRepositionFile, FW_DEFAULT); + dictAppendWord(dp, "file-status", ficlFileStatus, FW_DEFAULT); + dictAppendWord(dp, "flush-file", ficlFlushFile, FW_DEFAULT); + + dictAppendWord(dp, "delete-file", ficlDeleteFile, FW_DEFAULT); + dictAppendWord(dp, "rename-file", ficlRenameFile, FW_DEFAULT); + +#ifdef FICL_HAVE_FTRUNCATE + dictAppendWord(dp, "resize-file", ficlResizeFile, FW_DEFAULT); + + ficlSetEnv(pSys, "file", FICL_TRUE); + ficlSetEnv(pSys, "file-ext", FICL_TRUE); +#endif /* FICL_HAVE_FTRUNCATE */ +#else + &pSys; +#endif /* FICL_WANT_FILE */ +} diff --git a/sys/boot/ficl/float.c b/sys/boot/ficl/float.c new file mode 100644 index 0000000000..a2bf189b26 --- /dev/null +++ b/sys/boot/ficl/float.c @@ -0,0 +1,1067 @@ +/******************************************************************* +** f l o a t . c +** Forth Inspired Command Language +** ANS Forth FLOAT word-set written in C +** Author: Guy Carver & John Sadler (john_sadler@alum.mit.edu) +** Created: Apr 2001 +** $Id: float.c,v 1.8 2001/12/05 07:21:34 jsadler Exp $ +*******************************************************************/ +/* +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** +** I am interested in hearing from anyone who uses ficl. If you have +** a problem, a success story, a defect, an enhancement request, or +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +*/ + +/* + * $FreeBSD: src/sys/boot/ficl/float.c,v 1.1 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/float.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include +#include +#include +#include "ficl.h" + +#if FICL_WANT_FLOAT + +/******************************************************************* +** Do float addition r1 + r2. +** f+ ( r1 r2 -- r ) +*******************************************************************/ +static void Fadd(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 1); +#endif + + f = POPFLOAT(); + f += GETTOPF().f; + SETTOPF(f); +} + +/******************************************************************* +** Do float subtraction r1 - r2. +** f- ( r1 r2 -- r ) +*******************************************************************/ +static void Fsub(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 1); +#endif + + f = POPFLOAT(); + f = GETTOPF().f - f; + SETTOPF(f); +} + +/******************************************************************* +** Do float multiplication r1 * r2. +** f* ( r1 r2 -- r ) +*******************************************************************/ +static void Fmul(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 1); +#endif + + f = POPFLOAT(); + f *= GETTOPF().f; + SETTOPF(f); +} + +/******************************************************************* +** Do float negation. +** fnegate ( r -- r ) +*******************************************************************/ +static void Fnegate(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 1); +#endif + + f = -GETTOPF().f; + SETTOPF(f); +} + +/******************************************************************* +** Do float division r1 / r2. +** f/ ( r1 r2 -- r ) +*******************************************************************/ +static void Fdiv(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 1); +#endif + + f = POPFLOAT(); + f = GETTOPF().f / f; + SETTOPF(f); +} + +/******************************************************************* +** Do float + integer r + n. +** f+i ( r n -- r ) +*******************************************************************/ +static void Faddi(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 1); + vmCheckStack(pVM, 1, 0); +#endif + + f = (FICL_FLOAT)POPINT(); + f += GETTOPF().f; + SETTOPF(f); +} + +/******************************************************************* +** Do float - integer r - n. +** f-i ( r n -- r ) +*******************************************************************/ +static void Fsubi(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 1); + vmCheckStack(pVM, 1, 0); +#endif + + f = GETTOPF().f; + f -= (FICL_FLOAT)POPINT(); + SETTOPF(f); +} + +/******************************************************************* +** Do float * integer r * n. +** f*i ( r n -- r ) +*******************************************************************/ +static void Fmuli(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 1); + vmCheckStack(pVM, 1, 0); +#endif + + f = (FICL_FLOAT)POPINT(); + f *= GETTOPF().f; + SETTOPF(f); +} + +/******************************************************************* +** Do float / integer r / n. +** f/i ( r n -- r ) +*******************************************************************/ +static void Fdivi(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 1); + vmCheckStack(pVM, 1, 0); +#endif + + f = GETTOPF().f; + f /= (FICL_FLOAT)POPINT(); + SETTOPF(f); +} + +/******************************************************************* +** Do integer - float n - r. +** i-f ( n r -- r ) +*******************************************************************/ +static void isubf(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 1); + vmCheckStack(pVM, 1, 0); +#endif + + f = (FICL_FLOAT)POPINT(); + f -= GETTOPF().f; + SETTOPF(f); +} + +/******************************************************************* +** Do integer / float n / r. +** i/f ( n r -- r ) +*******************************************************************/ +static void idivf(FICL_VM *pVM) +{ + FICL_FLOAT f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1,1); + vmCheckStack(pVM, 1, 0); +#endif + + f = (FICL_FLOAT)POPINT(); + f /= GETTOPF().f; + SETTOPF(f); +} + +/******************************************************************* +** Do integer to float conversion. +** int>float ( n -- r ) +*******************************************************************/ +static void itof(FICL_VM *pVM) +{ + float f; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 1, 0); + vmCheckFStack(pVM, 0, 1); +#endif + + f = (float)POPINT(); + PUSHFLOAT(f); +} + +/******************************************************************* +** Do float to integer conversion. +** float>int ( r -- n ) +*******************************************************************/ +static void Ftoi(FICL_VM *pVM) +{ + FICL_INT i; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); + vmCheckFStack(pVM, 1, 0); +#endif + + i = (FICL_INT)POPFLOAT(); + PUSHINT(i); +} + +/******************************************************************* +** Floating point constant execution word. +*******************************************************************/ +void FconstantParen(FICL_VM *pVM) +{ + FICL_WORD *pFW = pVM->runningWord; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 0, 1); +#endif + + PUSHFLOAT(pFW->param[0].f); +} + +/******************************************************************* +** Create a floating point constant. +** fconstant ( r -"name"- ) +*******************************************************************/ +static void Fconstant(FICL_VM *pVM) +{ + FICL_DICT *dp = vmGetDict(pVM); + STRINGINFO si = vmGetWord(pVM); + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); +#endif + + dictAppendWord2(dp, si, FconstantParen, FW_DEFAULT); + dictAppendCell(dp, stackPop(pVM->fStack)); +} + +/******************************************************************* +** Display a float in decimal format. +** f. ( r -- ) +*******************************************************************/ +static void FDot(FICL_VM *pVM) +{ + float f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); +#endif + + f = POPFLOAT(); + sprintf(pVM->pad,"%#f ",f); + vmTextOut(pVM, pVM->pad, 0); +} + +/******************************************************************* +** Display a float in engineering format. +** fe. ( r -- ) +*******************************************************************/ +static void EDot(FICL_VM *pVM) +{ + float f; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); +#endif + + f = POPFLOAT(); + sprintf(pVM->pad,"%#e ",f); + vmTextOut(pVM, pVM->pad, 0); +} + +/************************************************************************** + d i s p l a y FS t a c k +** Display the parameter stack (code for "f.s") +** f.s ( -- ) +**************************************************************************/ +static void displayFStack(FICL_VM *pVM) +{ + int d = stackDepth(pVM->fStack); + int i; + CELL *pCell; + + vmCheckFStack(pVM, 0, 0); + + vmTextOut(pVM, "F:", 0); + + if (d == 0) + vmTextOut(pVM, "[0]", 0); + else + { + ltoa(d, &pVM->pad[1], pVM->base); + pVM->pad[0] = '['; + strcat(pVM->pad,"] "); + vmTextOut(pVM,pVM->pad,0); + + pCell = pVM->fStack->sp - d; + for (i = 0; i < d; i++) + { + sprintf(pVM->pad,"%#f ",(*pCell++).f); + vmTextOut(pVM,pVM->pad,0); + } + } +} + +/******************************************************************* +** Do float stack depth. +** fdepth ( -- n ) +*******************************************************************/ +static void Fdepth(FICL_VM *pVM) +{ + int i; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + + i = stackDepth(pVM->fStack); + PUSHINT(i); +} + +/******************************************************************* +** Do float stack drop. +** fdrop ( r -- ) +*******************************************************************/ +static void Fdrop(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); +#endif + + DROPF(1); +} + +/******************************************************************* +** Do float stack 2drop. +** f2drop ( r r -- ) +*******************************************************************/ +static void FtwoDrop(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 0); +#endif + + DROPF(2); +} + +/******************************************************************* +** Do float stack dup. +** fdup ( r -- r r ) +*******************************************************************/ +static void Fdup(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 2); +#endif + + PICKF(0); +} + +/******************************************************************* +** Do float stack 2dup. +** f2dup ( r1 r2 -- r1 r2 r1 r2 ) +*******************************************************************/ +static void FtwoDup(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 4); +#endif + + PICKF(1); + PICKF(1); +} + +/******************************************************************* +** Do float stack over. +** fover ( r1 r2 -- r1 r2 r1 ) +*******************************************************************/ +static void Fover(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 3); +#endif + + PICKF(1); +} + +/******************************************************************* +** Do float stack 2over. +** f2over ( r1 r2 r3 -- r1 r2 r3 r1 r2 ) +*******************************************************************/ +static void FtwoOver(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 4, 6); +#endif + + PICKF(3); + PICKF(3); +} + +/******************************************************************* +** Do float stack pick. +** fpick ( n -- r ) +*******************************************************************/ +static void Fpick(FICL_VM *pVM) +{ + CELL c = POP(); + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, c.i+1, c.i+2); +#endif + + PICKF(c.i); +} + +/******************************************************************* +** Do float stack ?dup. +** f?dup ( r -- r ) +*******************************************************************/ +static void FquestionDup(FICL_VM *pVM) +{ + CELL c; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 2); +#endif + + c = GETTOPF(); + if (c.f != 0) + PICKF(0); +} + +/******************************************************************* +** Do float stack roll. +** froll ( n -- ) +*******************************************************************/ +static void Froll(FICL_VM *pVM) +{ + int i = POP().i; + i = (i > 0) ? i : 0; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, i+1, i+1); +#endif + + ROLLF(i); +} + +/******************************************************************* +** Do float stack -roll. +** f-roll ( n -- ) +*******************************************************************/ +static void FminusRoll(FICL_VM *pVM) +{ + int i = POP().i; + i = (i > 0) ? i : 0; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, i+1, i+1); +#endif + + ROLLF(-i); +} + +/******************************************************************* +** Do float stack rot. +** frot ( r1 r2 r3 -- r2 r3 r1 ) +*******************************************************************/ +static void Frot(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 3, 3); +#endif + + ROLLF(2); +} + +/******************************************************************* +** Do float stack -rot. +** f-rot ( r1 r2 r3 -- r3 r1 r2 ) +*******************************************************************/ +static void Fminusrot(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 3, 3); +#endif + + ROLLF(-2); +} + +/******************************************************************* +** Do float stack swap. +** fswap ( r1 r2 -- r2 r1 ) +*******************************************************************/ +static void Fswap(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 2); +#endif + + ROLLF(1); +} + +/******************************************************************* +** Do float stack 2swap +** f2swap ( r1 r2 r3 r4 -- r3 r4 r1 r2 ) +*******************************************************************/ +static void FtwoSwap(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 4, 4); +#endif + + ROLLF(3); + ROLLF(3); +} + +/******************************************************************* +** Get a floating point number from a variable. +** f@ ( n -- r ) +*******************************************************************/ +static void Ffetch(FICL_VM *pVM) +{ + CELL *pCell; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 0, 1); + vmCheckStack(pVM, 1, 0); +#endif + + pCell = (CELL *)POPPTR(); + PUSHFLOAT(pCell->f); +} + +/******************************************************************* +** Store a floating point number into a variable. +** f! ( r n -- ) +*******************************************************************/ +static void Fstore(FICL_VM *pVM) +{ + CELL *pCell; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); + vmCheckStack(pVM, 1, 0); +#endif + + pCell = (CELL *)POPPTR(); + pCell->f = POPFLOAT(); +} + +/******************************************************************* +** Add a floating point number to contents of a variable. +** f+! ( r n -- ) +*******************************************************************/ +static void FplusStore(FICL_VM *pVM) +{ + CELL *pCell; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 1, 0); + vmCheckFStack(pVM, 1, 0); +#endif + + pCell = (CELL *)POPPTR(); + pCell->f += POPFLOAT(); +} + +/******************************************************************* +** Floating point literal execution word. +*******************************************************************/ +static void fliteralParen(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + + PUSHFLOAT(*(float*)(pVM->ip)); + vmBranchRelative(pVM, 1); +} + +/******************************************************************* +** Compile a floating point literal. +*******************************************************************/ +static void fliteralIm(FICL_VM *pVM) +{ + FICL_DICT *dp = vmGetDict(pVM); + FICL_WORD *pfLitParen = ficlLookup(pVM->pSys, "(fliteral)"); + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); +#endif + + dictAppendCell(dp, LVALUEtoCELL(pfLitParen)); + dictAppendCell(dp, stackPop(pVM->fStack)); +} + +/******************************************************************* +** Do float 0= comparison r = 0.0. +** f0= ( r -- T/F ) +*******************************************************************/ +static void FzeroEquals(FICL_VM *pVM) +{ + CELL c; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); /* Make sure something on float stack. */ + vmCheckStack(pVM, 0, 1); /* Make sure room for result. */ +#endif + + c.i = FICL_BOOL(POPFLOAT() == 0); + PUSH(c); +} + +/******************************************************************* +** Do float 0< comparison r < 0.0. +** f0< ( r -- T/F ) +*******************************************************************/ +static void FzeroLess(FICL_VM *pVM) +{ + CELL c; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); /* Make sure something on float stack. */ + vmCheckStack(pVM, 0, 1); /* Make sure room for result. */ +#endif + + c.i = FICL_BOOL(POPFLOAT() < 0); + PUSH(c); +} + +/******************************************************************* +** Do float 0> comparison r > 0.0. +** f0> ( r -- T/F ) +*******************************************************************/ +static void FzeroGreater(FICL_VM *pVM) +{ + CELL c; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); + vmCheckStack(pVM, 0, 1); +#endif + + c.i = FICL_BOOL(POPFLOAT() > 0); + PUSH(c); +} + +/******************************************************************* +** Do float = comparison r1 = r2. +** f= ( r1 r2 -- T/F ) +*******************************************************************/ +static void FisEqual(FICL_VM *pVM) +{ + float x, y; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 0); + vmCheckStack(pVM, 0, 1); +#endif + + x = POPFLOAT(); + y = POPFLOAT(); + PUSHINT(FICL_BOOL(x == y)); +} + +/******************************************************************* +** Do float < comparison r1 < r2. +** f< ( r1 r2 -- T/F ) +*******************************************************************/ +static void FisLess(FICL_VM *pVM) +{ + float x, y; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 0); + vmCheckStack(pVM, 0, 1); +#endif + + y = POPFLOAT(); + x = POPFLOAT(); + PUSHINT(FICL_BOOL(x < y)); +} + +/******************************************************************* +** Do float > comparison r1 > r2. +** f> ( r1 r2 -- T/F ) +*******************************************************************/ +static void FisGreater(FICL_VM *pVM) +{ + float x, y; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 2, 0); + vmCheckStack(pVM, 0, 1); +#endif + + y = POPFLOAT(); + x = POPFLOAT(); + PUSHINT(FICL_BOOL(x > y)); +} + + +/******************************************************************* +** Move float to param stack (assumes they both fit in a single CELL) +** f>s +*******************************************************************/ +static void FFrom(FICL_VM *pVM) +{ + CELL c; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 1, 0); + vmCheckStack(pVM, 0, 1); +#endif + + c = stackPop(pVM->fStack); + stackPush(pVM->pStack, c); + return; +} + +static void ToF(FICL_VM *pVM) +{ + CELL c; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 0, 1); + vmCheckStack(pVM, 1, 0); +#endif + + c = stackPop(pVM->pStack); + stackPush(pVM->fStack, c); + return; +} + + +/************************************************************************** + F l o a t P a r s e S t a t e +** Enum to determine the current segement of a floating point number +** being parsed. +**************************************************************************/ +#define NUMISNEG 1 +#define EXPISNEG 2 + +typedef enum _floatParseState +{ + FPS_START, + FPS_ININT, + FPS_INMANT, + FPS_STARTEXP, + FPS_INEXP +} FloatParseState; + +/************************************************************************** + f i c l P a r s e F l o a t N u m b e r +** pVM -- Virtual Machine pointer. +** si -- String to parse. +** Returns 1 if successful, 0 if not. +**************************************************************************/ +int ficlParseFloatNumber( FICL_VM *pVM, STRINGINFO si ) +{ + unsigned char ch, digit; + char *cp; + FICL_COUNT count; + float power; + float accum = 0.0f; + float mant = 0.1f; + FICL_INT exponent = 0; + char flag = 0; + FloatParseState estate = FPS_START; + +#if FICL_ROBUST > 1 + vmCheckFStack(pVM, 0, 1); +#endif + + /* + ** floating point numbers only allowed in base 10 + */ + if (pVM->base != 10) + return(0); + + + cp = SI_PTR(si); + count = (FICL_COUNT)SI_COUNT(si); + + /* Loop through the string's characters. */ + while ((count--) && ((ch = *cp++) != 0)) + { + switch (estate) + { + /* At start of the number so look for a sign. */ + case FPS_START: + { + estate = FPS_ININT; + if (ch == '-') + { + flag |= NUMISNEG; + break; + } + if (ch == '+') + { + break; + } + } /* Note! Drop through to FPS_ININT */ + /* + **Converting integer part of number. + ** Only allow digits, decimal and 'E'. + */ + case FPS_ININT: + { + if (ch == '.') + { + estate = FPS_INMANT; + } + else if ((ch == 'e') || (ch == 'E')) + { + estate = FPS_STARTEXP; + } + else + { + digit = (unsigned char)(ch - '0'); + if (digit > 9) + return(0); + + accum = accum * 10 + digit; + + } + break; + } + /* + ** Processing the fraction part of number. + ** Only allow digits and 'E' + */ + case FPS_INMANT: + { + if ((ch == 'e') || (ch == 'E')) + { + estate = FPS_STARTEXP; + } + else + { + digit = (unsigned char)(ch - '0'); + if (digit > 9) + return(0); + + accum += digit * mant; + mant *= 0.1f; + } + break; + } + /* Start processing the exponent part of number. */ + /* Look for sign. */ + case FPS_STARTEXP: + { + estate = FPS_INEXP; + + if (ch == '-') + { + flag |= EXPISNEG; + break; + } + else if (ch == '+') + { + break; + } + } /* Note! Drop through to FPS_INEXP */ + /* + ** Processing the exponent part of number. + ** Only allow digits. + */ + case FPS_INEXP: + { + digit = (unsigned char)(ch - '0'); + if (digit > 9) + return(0); + + exponent = exponent * 10 + digit; + + break; + } + } + } + + /* If parser never made it to the exponent this is not a float. */ + if (estate < FPS_STARTEXP) + return(0); + + /* Set the sign of the number. */ + if (flag & NUMISNEG) + accum = -accum; + + /* If exponent is not 0 then adjust number by it. */ + if (exponent != 0) + { + /* Determine if exponent is negative. */ + if (flag & EXPISNEG) + { + exponent = -exponent; + } + /* power = 10^x */ + power = (float)pow(10.0, exponent); + accum *= power; + } + + PUSHFLOAT(accum); + + return(1); +} + +#endif /* FICL_WANT_FLOAT */ + +/************************************************************************** +** Add float words to a system's dictionary. +** pSys -- Pointer to the FICL sytem to add float words to. +**************************************************************************/ +void ficlCompileFloat(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert(dp); + +#if FICL_WANT_FLOAT + dictAppendWord(dp, ">float", ToF, FW_DEFAULT); + /* d>f */ + dictAppendWord(dp, "f!", Fstore, FW_DEFAULT); + dictAppendWord(dp, "f*", Fmul, FW_DEFAULT); + dictAppendWord(dp, "f+", Fadd, FW_DEFAULT); + dictAppendWord(dp, "f-", Fsub, FW_DEFAULT); + dictAppendWord(dp, "f/", Fdiv, FW_DEFAULT); + dictAppendWord(dp, "f0<", FzeroLess, FW_DEFAULT); + dictAppendWord(dp, "f0=", FzeroEquals, FW_DEFAULT); + dictAppendWord(dp, "f<", FisLess, FW_DEFAULT); + /* + f>d + */ + dictAppendWord(dp, "f@", Ffetch, FW_DEFAULT); + /* + falign + faligned + */ + dictAppendWord(dp, "fconstant", Fconstant, FW_DEFAULT); + dictAppendWord(dp, "fdepth", Fdepth, FW_DEFAULT); + dictAppendWord(dp, "fdrop", Fdrop, FW_DEFAULT); + dictAppendWord(dp, "fdup", Fdup, FW_DEFAULT); + dictAppendWord(dp, "fliteral", fliteralIm, FW_IMMEDIATE); +/* + float+ + floats + floor + fmax + fmin +*/ + dictAppendWord(dp, "f?dup", FquestionDup, FW_DEFAULT); + dictAppendWord(dp, "f=", FisEqual, FW_DEFAULT); + dictAppendWord(dp, "f>", FisGreater, FW_DEFAULT); + dictAppendWord(dp, "f0>", FzeroGreater, FW_DEFAULT); + dictAppendWord(dp, "f2drop", FtwoDrop, FW_DEFAULT); + dictAppendWord(dp, "f2dup", FtwoDup, FW_DEFAULT); + dictAppendWord(dp, "f2over", FtwoOver, FW_DEFAULT); + dictAppendWord(dp, "f2swap", FtwoSwap, FW_DEFAULT); + dictAppendWord(dp, "f+!", FplusStore, FW_DEFAULT); + dictAppendWord(dp, "f+i", Faddi, FW_DEFAULT); + dictAppendWord(dp, "f-i", Fsubi, FW_DEFAULT); + dictAppendWord(dp, "f*i", Fmuli, FW_DEFAULT); + dictAppendWord(dp, "f/i", Fdivi, FW_DEFAULT); + dictAppendWord(dp, "int>float", itof, FW_DEFAULT); + dictAppendWord(dp, "float>int", Ftoi, FW_DEFAULT); + dictAppendWord(dp, "f.", FDot, FW_DEFAULT); + dictAppendWord(dp, "f.s", displayFStack, FW_DEFAULT); + dictAppendWord(dp, "fe.", EDot, FW_DEFAULT); + dictAppendWord(dp, "fover", Fover, FW_DEFAULT); + dictAppendWord(dp, "fnegate", Fnegate, FW_DEFAULT); + dictAppendWord(dp, "fpick", Fpick, FW_DEFAULT); + dictAppendWord(dp, "froll", Froll, FW_DEFAULT); + dictAppendWord(dp, "frot", Frot, FW_DEFAULT); + dictAppendWord(dp, "fswap", Fswap, FW_DEFAULT); + dictAppendWord(dp, "i-f", isubf, FW_DEFAULT); + dictAppendWord(dp, "i/f", idivf, FW_DEFAULT); + + dictAppendWord(dp, "float>", FFrom, FW_DEFAULT); + + dictAppendWord(dp, "f-roll", FminusRoll, FW_DEFAULT); + dictAppendWord(dp, "f-rot", Fminusrot, FW_DEFAULT); + dictAppendWord(dp, "(fliteral)", fliteralParen, FW_COMPILE); + + ficlSetEnv(pSys, "floating", FICL_FALSE); /* not all required words are present */ + ficlSetEnv(pSys, "floating-ext", FICL_FALSE); + ficlSetEnv(pSys, "floating-stack", FICL_DEFAULT_STACK); +#endif + return; +} diff --git a/sys/boot/ficl/i386/sysdep.c b/sys/boot/ficl/i386/sysdep.c index 2f17863698..2a391357e9 100644 --- a/sys/boot/ficl/i386/sysdep.c +++ b/sys/boot/ficl/i386/sysdep.c @@ -7,8 +7,10 @@ ** *******************************************************************/ -/* $FreeBSD: src/sys/boot/ficl/i386/sysdep.c,v 1.7 1999/09/29 04:43:07 dcs Exp $ */ -/* $DragonFly: src/sys/boot/ficl/i386/sysdep.c,v 1.2 2003/06/17 04:28:18 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/i386/sysdep.c,v 1.7 1999/09/29 04:43:07 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/i386/sysdep.c,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #ifdef TESTMAIN #include diff --git a/sys/boot/ficl/i386/sysdep.h b/sys/boot/ficl/i386/sysdep.h index 883a4f7b4d..86a7d01cd8 100644 --- a/sys/boot/ficl/i386/sysdep.h +++ b/sys/boot/ficl/i386/sysdep.h @@ -9,31 +9,47 @@ ** FICL_ROBUST is enabled. This may require some consideration ** in firmware systems since assert often ** assumes stderr/stdout. -** +** $Id: sysdep.h,v 1.11 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ /* -** N O T I C E -- DISCLAIMER OF WARRANTY -** -** Ficl is freeware. Use it in any way that you like, with -** the understanding that the code is not supported. -** -** Any third party may reproduce, distribute, or modify the ficl -** software code or any derivative works thereof without any -** compensation or license, provided that the author information -** and this disclaimer text are retained in the source code files. -** The ficl software code is provided on an "as is" basis without -** warranty of any kind, including, without limitation, the implied -** warranties of merchantability and fitness for a particular purpose -** and their equivalents under the laws of any jurisdiction. -** +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** ** I am interested in hearing from anyone who uses ficl. If you have ** a problem, a success story, a defect, an enhancement request, or -** if you would like to contribute to the ficl release (yay!), please -** send me email at the address above. +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ -/* $FreeBSD: src/sys/boot/ficl/i386/sysdep.h,v 1.5 1999/11/23 15:24:30 dcs Exp $ */ -/* $DragonFly: src/sys/boot/ficl/i386/sysdep.h,v 1.2 2003/06/17 04:28:18 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/i386/sysdep.h,v 1.8 2002/05/16 21:21:52 trhodes Exp $ + * $DragonFly: src/sys/boot/ficl/i386/sysdep.h,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #if !defined (__SYSDEP_H__) #define __SYSDEP_H__ @@ -42,14 +58,12 @@ #include /* size_t, NULL */ #include - #include #if !defined IGNORE /* Macro to silence unused param warnings */ #define IGNORE(x) &x #endif - /* ** TRUE and FALSE for C boolean operations, and ** portable 32 bit types for CELLs @@ -62,7 +76,6 @@ #define FALSE 0 #endif - /* ** System dependent data type declarations... */ @@ -90,6 +103,7 @@ ** FICL_UNS and FICL_INT must have the same size as a void* on ** the target system. A CELL is a union of void*, FICL_UNS, and ** FICL_INT. +** (11/2000: same for FICL_FLOAT) */ #if !defined FICL_INT #define FICL_INT INT32 @@ -99,6 +113,10 @@ #define FICL_UNS UNS32 #endif +#if !defined FICL_FLOAT +#define FICL_FLOAT float +#endif + /* ** Ficl presently supports values of 32 and 64 for BITS_PER_CELL */ @@ -136,9 +154,128 @@ typedef struct /* -** Build controls +** B U I L D C O N T R O L S +*/ + +#if !defined (FICL_MINIMAL) +#define FICL_MINIMAL 0 +#endif +#if (FICL_MINIMAL) +#define FICL_WANT_SOFTWORDS 0 +#define FICL_WANT_FILE 0 +#define FICL_WANT_FLOAT 0 +#define FICL_WANT_USER 0 +#define FICL_WANT_LOCALS 0 +#define FICL_WANT_DEBUGGER 0 +#define FICL_WANT_OOP 0 +#define FICL_PLATFORM_EXTEND 0 +#define FICL_MULTITHREAD 0 +#define FICL_ROBUST 0 +#define FICL_EXTENDED_PREFIX 0 +#endif + +/* +** FICL_PLATFORM_EXTEND +** Includes words defined in ficlCompilePlatform +*/ +#if !defined (FICL_PLATFORM_EXTEND) +#define FICL_PLATFORM_EXTEND 1 +#endif + + +/* +** FICL_WANT_FILE +** Includes the FILE and FILE-EXT wordset and associated code. Turn this off if you do not +** have a filesystem! +** Contributed by Larry Hastings +*/ +#if !defined (FICL_WANT_FILE) +#define FICL_WANT_FILE 0 +#endif + +/* +** FICL_WANT_FLOAT +** Includes a floating point stack for the VM, and words to do float operations. +** Contributed by Guy Carver +*/ +#if !defined (FICL_WANT_FLOAT) +#define FICL_WANT_FLOAT 0 +#endif + +/* +** FICL_WANT_DEBUGGER +** Inludes a simple source level debugger +*/ +#if !defined (FICL_WANT_DEBUGGER) +#define FICL_WANT_DEBUGGER 1 +#endif + +/* +** FICL_EXTENDED_PREFIX enables a bunch of extra prefixes in prefix.c and prefix.fr (if +** included as part of softcore.c) +*/ +#if !defined FICL_EXTENDED_PREFIX +#define FICL_EXTENDED_PREFIX 0 +#endif + +/* +** User variables: per-instance variables bound to the VM. +** Kinda like thread-local storage. Could be implemented in a +** VM private dictionary, but I've chosen the lower overhead +** approach of an array of CELLs instead. +*/ +#if !defined FICL_WANT_USER +#define FICL_WANT_USER 1 +#endif + +#if !defined FICL_USER_CELLS +#define FICL_USER_CELLS 16 +#endif + +/* +** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and +** a private dictionary for local variable compilation. +*/ +#if !defined FICL_WANT_LOCALS +#define FICL_WANT_LOCALS 1 +#endif + +/* Max number of local variables per definition */ +#if !defined FICL_MAX_LOCALS +#define FICL_MAX_LOCALS 16 +#endif + +/* +** FICL_WANT_OOP +** Inludes object oriented programming support (in softwords) +** OOP support requires locals and user variables! +*/ +#if !(FICL_WANT_LOCALS) || !(FICL_WANT_USER) +#if !defined (FICL_WANT_OOP) +#define FICL_WANT_OOP 0 +#endif +#endif + +#if !defined (FICL_WANT_OOP) +#define FICL_WANT_OOP 1 +#endif + +/* +** FICL_WANT_SOFTWORDS +** Controls inclusion of all softwords in softcore.c +*/ +#if !defined (FICL_WANT_SOFTWORDS) +#define FICL_WANT_SOFTWORDS 1 +#endif + +/* ** FICL_MULTITHREAD enables dictionary mutual exclusion ** wia the ficlLockDictionary system dependent function. +** Note: this implementation is experimental and poorly +** tested. Further, it's unnecessary unless you really +** intend to have multiple SESSIONS (poor choice of name +** on my part) - that is, threads that modify the dictionary +** at the same time. */ #if !defined FICL_MULTITHREAD #define FICL_MULTITHREAD 0 @@ -153,7 +290,6 @@ typedef struct #define PORTABLE_LONGMULDIV 0 #endif - /* ** INLINE_INNER_LOOP causes the inner interpreter to be inline code ** instead of a function call. This is mainly because MS VC++ 5 @@ -215,30 +351,13 @@ typedef struct #endif /* -** User variables: per-instance variables bound to the VM. -** Kinda like thread-local storage. Could be implemented in a -** VM private dictionary, but I've chosen the lower overhead -** approach of an array of CELLs instead. +** FICL_MAX_PARSE_STEPS controls the size of an array in the FICL_SYSTEM structure +** that stores pointers to parser extension functions. I would never expect to have +** more than 8 of these, so that's the default limit. Too many of these functions +** will probably exact a nasty performance penalty. */ -#if !defined FICL_WANT_USER -#define FICL_WANT_USER 1 -#endif - -#if !defined FICL_USER_CELLS -#define FICL_USER_CELLS 16 -#endif - -/* -** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and -** a private dictionary for local variable compilation. -*/ -#if !defined FICL_WANT_LOCALS -#define FICL_WANT_LOCALS 1 -#endif - -/* Max number of local variables per definition */ -#if !defined FICL_MAX_LOCALS -#define FICL_MAX_LOCALS 16 +#if !defined FICL_MAX_PARSE_STEPS +#define FICL_MAX_PARSE_STEPS 8 #endif /* @@ -302,4 +421,15 @@ int ficlLockDictionary(short fLock); DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y); UNSQR ficlLongDiv(DPUNS q, FICL_UNS y); + +/* +** FICL_HAVE_FTRUNCATE indicates whether the current OS supports +** the ftruncate() function (available on most UNIXes). This +** function is necessary to provide the complete File-Access wordset. +*/ +#if !defined (FICL_HAVE_FTRUNCATE) +#define FICL_HAVE_FTRUNCATE 0 +#endif + + #endif /*__SYSDEP_H__*/ diff --git a/sys/boot/ficl/alpha/sysdep.c b/sys/boot/ficl/ia64/sysdep.c similarity index 91% copy from sys/boot/ficl/alpha/sysdep.c copy to sys/boot/ficl/ia64/sysdep.c index 4d4d6a010e..673223e55a 100644 --- a/sys/boot/ficl/alpha/sysdep.c +++ b/sys/boot/ficl/ia64/sysdep.c @@ -7,8 +7,10 @@ ** *******************************************************************/ -/* $FreeBSD: src/sys/boot/ficl/alpha/sysdep.c,v 1.7.2.1 2000/07/06 23:51:46 obrien Exp $ */ -/* $DragonFly: src/sys/boot/ficl/alpha/Attic/sysdep.c,v 1.2 2003/06/17 04:28:18 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/ia64/sysdep.c,v 1.1 2001/09/04 08:50:23 dfr Exp $ + * $DragonFly: src/sys/boot/ficl/ia64/sysdep.c,v 1.1 2003/11/10 06:08:34 dillon Exp $ + */ #ifdef TESTMAIN #include diff --git a/sys/boot/ficl/alpha/sysdep.h b/sys/boot/ficl/ia64/sysdep.h similarity index 59% copy from sys/boot/ficl/alpha/sysdep.h copy to sys/boot/ficl/ia64/sysdep.h index 5fef14d6e0..94f3ac1c11 100644 --- a/sys/boot/ficl/alpha/sysdep.h +++ b/sys/boot/ficl/ia64/sysdep.h @@ -9,31 +9,49 @@ ** FICL_ROBUST is enabled. This may require some consideration ** in firmware systems since assert often ** assumes stderr/stdout. -** +** $Id: sysdep.h,v 1.11 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ /* -** N O T I C E -- DISCLAIMER OF WARRANTY -** -** Ficl is freeware. Use it in any way that you like, with -** the understanding that the code is not supported. -** -** Any third party may reproduce, distribute, or modify the ficl -** software code or any derivative works thereof without any -** compensation or license, provided that the author information -** and this disclaimer text are retained in the source code files. -** The ficl software code is provided on an "as is" basis without -** warranty of any kind, including, without limitation, the implied -** warranties of merchantability and fitness for a particular purpose -** and their equivalents under the laws of any jurisdiction. -** +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** ** I am interested in hearing from anyone who uses ficl. If you have ** a problem, a success story, a defect, an enhancement request, or -** if you would like to contribute to the ficl release (yay!), please -** send me email at the address above. +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +** +** $Id: sysdep.h,v 1.6 2001-04-26 21:41:55-07 jsadler Exp jsadler $ */ -/* $FreeBSD: src/sys/boot/ficl/alpha/sysdep.h,v 1.5.2.1 2000/07/06 23:51:46 obrien Exp $ */ -/* $DragonFly: src/sys/boot/ficl/alpha/Attic/sysdep.h,v 1.2 2003/06/17 04:28:18 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/ia64/sysdep.h,v 1.3 2002/05/16 21:21:57 trhodes Exp $ + * $DragonFly: src/sys/boot/ficl/ia64/sysdep.h,v 1.1 2003/11/10 06:08:34 dillon Exp $ + */ #if !defined (__SYSDEP_H__) #define __SYSDEP_H__ @@ -42,14 +60,12 @@ #include /* size_t, NULL */ #include - #include #if !defined IGNORE /* Macro to silence unused param warnings */ #define IGNORE(x) &x #endif - /* ** TRUE and FALSE for C boolean operations, and ** portable 32 bit types for CELLs @@ -62,7 +78,6 @@ #define FALSE 0 #endif - /* ** System dependent data type declarations... */ @@ -90,6 +105,7 @@ ** FICL_UNS and FICL_INT must have the same size as a void* on ** the target system. A CELL is a union of void*, FICL_UNS, and ** FICL_INT. +** (11/2000: same for FICL_FLOAT) */ #if !defined FICL_INT #define FICL_INT long @@ -99,6 +115,10 @@ #define FICL_UNS unsigned long #endif +#if !defined FICL_FLOAT +#define FICL_FLOAT float +#endif + /* ** Ficl presently supports values of 32 and 64 for BITS_PER_CELL */ @@ -136,9 +156,128 @@ typedef struct /* -** Build controls +** B U I L D C O N T R O L S +*/ + +#if !defined (FICL_MINIMAL) +#define FICL_MINIMAL 0 +#endif +#if (FICL_MINIMAL) +#define FICL_WANT_SOFTWORDS 0 +#define FICL_WANT_FILE 0 +#define FICL_WANT_FLOAT 0 +#define FICL_WANT_USER 0 +#define FICL_WANT_LOCALS 0 +#define FICL_WANT_DEBUGGER 0 +#define FICL_WANT_OOP 0 +#define FICL_PLATFORM_EXTEND 0 +#define FICL_MULTITHREAD 0 +#define FICL_ROBUST 0 +#define FICL_EXTENDED_PREFIX 0 +#endif + +/* +** FICL_PLATFORM_EXTEND +** Includes words defined in ficlCompilePlatform +*/ +#if !defined (FICL_PLATFORM_EXTEND) +#define FICL_PLATFORM_EXTEND 1 +#endif + + +/* +** FICL_WANT_FILE +** Includes the FILE and FILE-EXT wordset and associated code. Turn this off if you do not +** have a filesystem! +** Contributed by Larry Hastings +*/ +#if !defined (FICL_WANT_FILE) +#define FICL_WANT_FILE 0 +#endif + +/* +** FICL_WANT_FLOAT +** Includes a floating point stack for the VM, and words to do float operations. +** Contributed by Guy Carver +*/ +#if !defined (FICL_WANT_FLOAT) +#define FICL_WANT_FLOAT 0 +#endif + +/* +** FICL_WANT_DEBUGGER +** Inludes a simple source level debugger +*/ +#if !defined (FICL_WANT_DEBUGGER) +#define FICL_WANT_DEBUGGER 1 +#endif + +/* +** FICL_EXTENDED_PREFIX enables a bunch of extra prefixes in prefix.c and prefix.fr (if +** included as part of softcore.c) +*/ +#if !defined FICL_EXTENDED_PREFIX +#define FICL_EXTENDED_PREFIX 0 +#endif + +/* +** User variables: per-instance variables bound to the VM. +** Kinda like thread-local storage. Could be implemented in a +** VM private dictionary, but I've chosen the lower overhead +** approach of an array of CELLs instead. +*/ +#if !defined FICL_WANT_USER +#define FICL_WANT_USER 1 +#endif + +#if !defined FICL_USER_CELLS +#define FICL_USER_CELLS 16 +#endif + +/* +** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and +** a private dictionary for local variable compilation. +*/ +#if !defined FICL_WANT_LOCALS +#define FICL_WANT_LOCALS 1 +#endif + +/* Max number of local variables per definition */ +#if !defined FICL_MAX_LOCALS +#define FICL_MAX_LOCALS 16 +#endif + +/* +** FICL_WANT_OOP +** Inludes object oriented programming support (in softwords) +** OOP support requires locals and user variables! +*/ +#if !(FICL_WANT_LOCALS) || !(FICL_WANT_USER) +#if !defined (FICL_WANT_OOP) +#define FICL_WANT_OOP 0 +#endif +#endif + +#if !defined (FICL_WANT_OOP) +#define FICL_WANT_OOP 1 +#endif + +/* +** FICL_WANT_SOFTWORDS +** Controls inclusion of all softwords in softcore.c +*/ +#if !defined (FICL_WANT_SOFTWORDS) +#define FICL_WANT_SOFTWORDS 1 +#endif + +/* ** FICL_MULTITHREAD enables dictionary mutual exclusion ** wia the ficlLockDictionary system dependent function. +** Note: this implementation is experimental and poorly +** tested. Further, it's unnecessary unless you really +** intend to have multiple SESSIONS (poor choice of name +** on my part) - that is, threads that modify the dictionary +** at the same time. */ #if !defined FICL_MULTITHREAD #define FICL_MULTITHREAD 0 @@ -153,7 +292,6 @@ typedef struct #define PORTABLE_LONGMULDIV 0 #endif - /* ** INLINE_INNER_LOOP causes the inner interpreter to be inline code ** instead of a function call. This is mainly because MS VC++ 5 @@ -215,30 +353,13 @@ typedef struct #endif /* -** User variables: per-instance variables bound to the VM. -** Kinda like thread-local storage. Could be implemented in a -** VM private dictionary, but I've chosen the lower overhead -** approach of an array of CELLs instead. +** FICL_MAX_PARSE_STEPS controls the size of an array in the FICL_SYSTEM structure +** that stores pointers to parser extension functions. I would never expect to have +** more than 8 of these, so that's the default limit. Too many of these functions +** will probably exact a nasty performance penalty. */ -#if !defined FICL_WANT_USER -#define FICL_WANT_USER 1 -#endif - -#if !defined FICL_USER_CELLS -#define FICL_USER_CELLS 16 -#endif - -/* -** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and -** a private dictionary for local variable compilation. -*/ -#if !defined FICL_WANT_LOCALS -#define FICL_WANT_LOCALS 1 -#endif - -/* Max number of local variables per definition */ -#if !defined FICL_MAX_LOCALS -#define FICL_MAX_LOCALS 16 +#if !defined FICL_MAX_PARSE_STEPS +#define FICL_MAX_PARSE_STEPS 8 #endif /* @@ -302,4 +423,15 @@ int ficlLockDictionary(short fLock); DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y); UNSQR ficlLongDiv(DPUNS q, FICL_UNS y); + +/* +** FICL_HAVE_FTRUNCATE indicates whether the current OS supports +** the ftruncate() function (available on most UNIXes). This +** function is necessary to provide the complete File-Access wordset. +*/ +#if !defined (FICL_HAVE_FTRUNCATE) +#define FICL_HAVE_FTRUNCATE 0 +#endif + + #endif /*__SYSDEP_H__*/ diff --git a/sys/boot/ficl/loader.c b/sys/boot/ficl/loader.c index 8803c08614..fb696782ea 100644 --- a/sys/boot/ficl/loader.c +++ b/sys/boot/ficl/loader.c @@ -23,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/boot/ficl/loader.c,v 1.1.2.1 2000/07/06 23:44:59 obrien Exp $ - * $DragonFly: src/sys/boot/ficl/loader.c,v 1.2 2003/06/17 04:28:17 dillon Exp $ + * $FreeBSD: src/sys/boot/ficl/loader.c,v 1.9 2003/06/08 03:11:16 nyan Exp $ + * $DragonFly: src/sys/boot/ficl/loader.c,v 1.3 2003/11/10 06:08:33 dillon Exp $ */ /******************************************************************* @@ -33,12 +33,16 @@ ** *******************************************************************/ +#ifdef TESTMAIN +#include +#else #include +#endif #include "bootstrap.h" #include #include "ficl.h" -/* FreeBSD's loader interaction words +/* FreeBSD's loader interaction words and extras * * setenv ( value n name n' -- ) * setenv? ( value n name n' flag -- ) @@ -46,8 +50,14 @@ * unsetenv ( addr n -- ) * copyin ( addr addr' len -- ) * copyout ( addr addr' len -- ) + * findfile ( name len type len' -- addr ) + * pnpdevices ( -- addr ) + * pnphandlers ( -- addr ) + * ccall ( [[...[p10] p9] ... p1] n addr -- result ) + * .# ( value -- ) */ +#ifndef TESTMAIN void ficlSetenv(FICL_VM *pVM) { @@ -207,3 +217,462 @@ ficlCopyout(FICL_VM *pVM) return; } +void +ficlFindfile(FICL_VM *pVM) +{ + char *name, *type, *namep, *typep; + struct preloaded_file* fp; + int names, types; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 4, 1); +#endif + + types = stackPopINT(pVM->pStack); + typep = (char*) stackPopPtr(pVM->pStack); + names = stackPopINT(pVM->pStack); + namep = (char*) stackPopPtr(pVM->pStack); + name = (char*) ficlMalloc(names+1); + if (!name) + vmThrowErr(pVM, "Error: out of memory"); + strncpy(name, namep, names); + name[names] = '\0'; + type = (char*) ficlMalloc(types+1); + if (!type) + vmThrowErr(pVM, "Error: out of memory"); + strncpy(type, typep, types); + type[types] = '\0'; + + fp = file_findfile(name, type); + stackPushPtr(pVM->pStack, fp); + + return; +} + +#ifdef HAVE_PNP + +void +ficlPnpdevices(FICL_VM *pVM) +{ + static int pnp_devices_initted = 0; +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + + if(!pnp_devices_initted) { + STAILQ_INIT(&pnp_devices); + pnp_devices_initted = 1; + } + + stackPushPtr(pVM->pStack, &pnp_devices); + + return; +} + +void +ficlPnphandlers(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + + stackPushPtr(pVM->pStack, pnphandlers); + + return; +} + +#endif + +#endif /* ndef TESTMAIN */ + +void +ficlCcall(FICL_VM *pVM) +{ + int (*func)(int, ...); + int result, p[10]; + int nparam, i; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 2, 0); +#endif + + func = stackPopPtr(pVM->pStack); + nparam = stackPopINT(pVM->pStack); + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, nparam, 1); +#endif + + for (i = 0; i < nparam; i++) + p[i] = stackPopINT(pVM->pStack); + + result = func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], + p[9]); + + stackPushINT(pVM->pStack, result); + + return; +} + +/************************************************************************** + f i c l E x e c F D +** reads in text from file fd and passes it to ficlExec() + * returns VM_OUTOFTEXT on success or the ficlExec() error code on + * failure. + */ +#define nLINEBUF 256 +int ficlExecFD(FICL_VM *pVM, int fd) +{ + char cp[nLINEBUF]; + int nLine = 0, rval = VM_OUTOFTEXT; + char ch; + CELL id; + + id = pVM->sourceID; + pVM->sourceID.i = fd; + + /* feed each line to ficlExec */ + while (1) { + int status, i; + + i = 0; + while ((status = read(fd, &ch, 1)) > 0 && ch != '\n') + cp[i++] = ch; + nLine++; + if (!i) { + if (status < 1) + break; + continue; + } + rval = ficlExecC(pVM, cp, i); + if(rval != VM_QUIT && rval != VM_USEREXIT && rval != VM_OUTOFTEXT) + { + pVM->sourceID = id; + return rval; + } + } + /* + ** Pass an empty line with SOURCE-ID == -1 to flush + ** any pending REFILLs (as required by FILE wordset) + */ + pVM->sourceID.i = -1; + ficlExec(pVM, ""); + + pVM->sourceID = id; + return rval; +} + +static void displayCellNoPad(FICL_VM *pVM) +{ + CELL c; +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 1, 0); +#endif + c = stackPop(pVM->pStack); + ltoa((c).i, pVM->pad, pVM->base); + vmTextOut(pVM, pVM->pad, 0); + return; +} + +/* fopen - open a file and return new fd on stack. + * + * fopen ( ptr count mode -- fd ) + */ +static void pfopen(FICL_VM *pVM) +{ + int mode, fd, count; + char *ptr, *name; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 3, 1); +#endif + + mode = stackPopINT(pVM->pStack); /* get mode */ + count = stackPopINT(pVM->pStack); /* get count */ + ptr = stackPopPtr(pVM->pStack); /* get ptr */ + + if ((count < 0) || (ptr == NULL)) { + stackPushINT(pVM->pStack, -1); + return; + } + + /* ensure that the string is null terminated */ + name = (char *)malloc(count+1); + bcopy(ptr,name,count); + name[count] = 0; + + /* open the file */ + fd = open(name, mode); + free(name); + stackPushINT(pVM->pStack, fd); + return; +} + +/* fclose - close a file who's fd is on stack. + * + * fclose ( fd -- ) + */ +static void pfclose(FICL_VM *pVM) +{ + int fd; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 1, 0); +#endif + fd = stackPopINT(pVM->pStack); /* get fd */ + if (fd != -1) + close(fd); + return; +} + +/* fread - read file contents + * + * fread ( fd buf nbytes -- nread ) + */ +static void pfread(FICL_VM *pVM) +{ + int fd, len; + char *buf; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 3, 1); +#endif + len = stackPopINT(pVM->pStack); /* get number of bytes to read */ + buf = stackPopPtr(pVM->pStack); /* get buffer */ + fd = stackPopINT(pVM->pStack); /* get fd */ + if (len > 0 && buf && fd != -1) + stackPushINT(pVM->pStack, read(fd, buf, len)); + else + stackPushINT(pVM->pStack, -1); + return; +} + +/* fload - interpret file contents + * + * fload ( fd -- ) + */ +static void pfload(FICL_VM *pVM) +{ + int fd; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 1, 0); +#endif + fd = stackPopINT(pVM->pStack); /* get fd */ + if (fd != -1) + ficlExecFD(pVM, fd); + return; +} + +/* fwrite - write file contents + * + * fwrite ( fd buf nbytes -- nwritten ) + */ +static void pfwrite(FICL_VM *pVM) +{ + int fd, len; + char *buf; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 3, 1); +#endif + len = stackPopINT(pVM->pStack); /* get number of bytes to read */ + buf = stackPopPtr(pVM->pStack); /* get buffer */ + fd = stackPopINT(pVM->pStack); /* get fd */ + if (len > 0 && buf && fd != -1) + stackPushINT(pVM->pStack, write(fd, buf, len)); + else + stackPushINT(pVM->pStack, -1); + return; +} + +/* fseek - seek to a new position in a file + * + * fseek ( fd ofs whence -- pos ) + */ +static void pfseek(FICL_VM *pVM) +{ + int fd, pos, whence; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 3, 1); +#endif + whence = stackPopINT(pVM->pStack); + pos = stackPopINT(pVM->pStack); + fd = stackPopINT(pVM->pStack); + stackPushINT(pVM->pStack, lseek(fd, pos, whence)); + return; +} + +/* key - get a character from stdin + * + * key ( -- char ) + */ +static void key(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + stackPushINT(pVM->pStack, getchar()); + return; +} + +/* key? - check for a character from stdin (FACILITY) + * + * key? ( -- flag ) + */ +static void keyQuestion(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif +#ifdef TESTMAIN + /* XXX Since we don't fiddle with termios, let it always succeed... */ + stackPushINT(pVM->pStack, FICL_TRUE); +#else + /* But here do the right thing. */ + stackPushINT(pVM->pStack, ischar()? FICL_TRUE : FICL_FALSE); +#endif + return; +} + +/* seconds - gives number of seconds since beginning of time + * + * beginning of time is defined as: + * + * BTX - number of seconds since midnight + * FreeBSD - number of seconds since Jan 1 1970 + * + * seconds ( -- u ) + */ +static void pseconds(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckStack(pVM,0,1); +#endif + stackPushUNS(pVM->pStack, (FICL_UNS) time(NULL)); + return; +} + +/* ms - wait at least that many milliseconds (FACILITY) + * + * ms ( u -- ) + * + */ +static void ms(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckStack(pVM,1,0); +#endif +#ifdef TESTMAIN + usleep(stackPopUNS(pVM->pStack)*1000); +#else + delay(stackPopUNS(pVM->pStack)*1000); +#endif + return; +} + +/* fkey - get a character from a file + * + * fkey ( file -- char ) + */ +static void fkey(FICL_VM *pVM) +{ + int i, fd; + char ch; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 1, 1); +#endif + fd = stackPopINT(pVM->pStack); + i = read(fd, &ch, 1); + stackPushINT(pVM->pStack, i > 0 ? ch : -1); + return; +} + +/* +** Retrieves free space remaining on the dictionary +*/ + +static void freeHeap(FICL_VM *pVM) +{ + stackPushINT(pVM->pStack, dictCellsAvail(ficlGetDict(pVM->pSys))); +} + + +/******************* Increase dictionary size on-demand ******************/ + +static void ficlDictThreshold(FICL_VM *pVM) +{ + stackPushPtr(pVM->pStack, &dictThreshold); +} + +static void ficlDictIncrease(FICL_VM *pVM) +{ + stackPushPtr(pVM->pStack, &dictIncrease); +} + + +/************************************************************************** + f i c l C o m p i l e P l a t f o r m +** Build FreeBSD platform extensions into the system dictionary +**************************************************************************/ +void ficlCompilePlatform(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, ".#", displayCellNoPad, FW_DEFAULT); + dictAppendWord(dp, "fopen", pfopen, FW_DEFAULT); + dictAppendWord(dp, "fclose", pfclose, FW_DEFAULT); + dictAppendWord(dp, "fread", pfread, FW_DEFAULT); + dictAppendWord(dp, "fload", pfload, FW_DEFAULT); + dictAppendWord(dp, "fkey", fkey, FW_DEFAULT); + dictAppendWord(dp, "fseek", pfseek, FW_DEFAULT); + dictAppendWord(dp, "fwrite", pfwrite, FW_DEFAULT); + dictAppendWord(dp, "key", key, FW_DEFAULT); + dictAppendWord(dp, "key?", keyQuestion, FW_DEFAULT); + dictAppendWord(dp, "ms", ms, FW_DEFAULT); + dictAppendWord(dp, "seconds", pseconds, FW_DEFAULT); + dictAppendWord(dp, "heap?", freeHeap, FW_DEFAULT); + dictAppendWord(dp, "dictthreshold", ficlDictThreshold, FW_DEFAULT); + dictAppendWord(dp, "dictincrease", ficlDictIncrease, FW_DEFAULT); + +#ifndef TESTMAIN +#ifdef __i386__ + dictAppendWord(dp, "outb", ficlOutb, FW_DEFAULT); + dictAppendWord(dp, "inb", ficlInb, FW_DEFAULT); +#endif + dictAppendWord(dp, "setenv", ficlSetenv, FW_DEFAULT); + dictAppendWord(dp, "setenv?", ficlSetenvq, FW_DEFAULT); + dictAppendWord(dp, "getenv", ficlGetenv, FW_DEFAULT); + dictAppendWord(dp, "unsetenv", ficlUnsetenv, FW_DEFAULT); + dictAppendWord(dp, "copyin", ficlCopyin, FW_DEFAULT); + dictAppendWord(dp, "copyout", ficlCopyout, FW_DEFAULT); + dictAppendWord(dp, "findfile", ficlFindfile, FW_DEFAULT); +#ifdef HAVE_PNP + dictAppendWord(dp, "pnpdevices",ficlPnpdevices, FW_DEFAULT); + dictAppendWord(dp, "pnphandlers",ficlPnphandlers, FW_DEFAULT); +#endif + dictAppendWord(dp, "ccall", ficlCcall, FW_DEFAULT); +#endif + +#if defined(PC98) + ficlSetEnv(pSys, "arch-pc98", FICL_TRUE); +#elif defined(__i386__) + ficlSetEnv(pSys, "arch-i386", FICL_TRUE); + ficlSetEnv(pSys, "arch-alpha", FICL_FALSE); + ficlSetEnv(pSys, "arch-ia64", FICL_FALSE); +#elif defined(__alpha__) + ficlSetEnv(pSys, "arch-i386", FICL_FALSE); + ficlSetEnv(pSys, "arch-alpha", FICL_TRUE); + ficlSetEnv(pSys, "arch-ia64", FICL_FALSE); +#elif defined(__ia64__) + ficlSetEnv(pSys, "arch-i386", FICL_FALSE); + ficlSetEnv(pSys, "arch-alpha", FICL_FALSE); + ficlSetEnv(pSys, "arch-ia64", FICL_TRUE); +#endif + + return; +} + diff --git a/sys/boot/ficl/math64.c b/sys/boot/ficl/math64.c index 77bd7030ce..d0ac82605e 100644 --- a/sys/boot/ficl/math64.c +++ b/sys/boot/ficl/math64.c @@ -5,10 +5,47 @@ ** Created: 25 January 1998 ** Rev 2.03: Support for 128 bit DP math. This file really ouught to ** be renamed! +** $Id: math64.c,v 1.9 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ - -/* $FreeBSD: src/sys/boot/ficl/math64.c,v 1.2 1999/09/29 04:43:06 dcs Exp $ */ -/* $DragonFly: src/sys/boot/ficl/math64.c,v 1.2 2003/06/17 04:28:17 dillon Exp $ */ +/* +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** +** I am interested in hearing from anyone who uses ficl. If you have +** a problem, a success story, a defect, an enhancement request, or +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +*/ + +/* + * $FreeBSD: src/sys/boot/ficl/math64.c,v 1.4 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/math64.c,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #include "ficl.h" #include "math64.h" @@ -312,7 +349,7 @@ UNS16 m64UMod(DPUNS *pUD, UNS16 base) /************************************************************************** ** Contributed by -** Michael A. Gauland gaulandm@mdhost.cse.tek.com +** Michael A. Gauland gaulandm@mdhost.cse.tek.com **************************************************************************/ #if PORTABLE_LONGMULDIV != 0 /************************************************************************** @@ -455,7 +492,7 @@ int m64Compare(DPUNS x, DPUNS y) f i c l L o n g M u l ** Portable versions of ficlLongMul and ficlLongDiv in C ** Contributed by: -** Michael A. Gauland gaulandm@mdhost.cse.tek.com +** Michael A. Gauland gaulandm@mdhost.cse.tek.com **************************************************************************/ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) { @@ -482,7 +519,7 @@ DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y) f i c l L o n g D i v ** Portable versions of ficlLongMul and ficlLongDiv in C ** Contributed by: -** Michael A. Gauland gaulandm@mdhost.cse.tek.com +** Michael A. Gauland gaulandm@mdhost.cse.tek.com **************************************************************************/ UNSQR ficlLongDiv(DPUNS q, FICL_UNS y) { diff --git a/sys/boot/ficl/math64.h b/sys/boot/ficl/math64.h index 13e30b5dd2..471cf321df 100644 --- a/sys/boot/ficl/math64.h +++ b/sys/boot/ficl/math64.h @@ -3,35 +3,47 @@ ** Forth Inspired Command Language - 64 bit math support routines ** Author: John Sadler (john_sadler@alum.mit.edu) ** Created: 25 January 1998 -** +** $Id: math64.h,v 1.9 2001/12/05 07:21:34 jsadler Exp $ *******************************************************************/ /* -** N O T I C E -- DISCLAIMER OF WARRANTY -** -** Ficl is freeware. Use it in any way that you like, with -** the understanding that the code is not supported. -** -** Any third party may reproduce, distribute, or modify the ficl -** software code or any derivative works thereof without any -** compensation or license, provided that the author information -** and this disclaimer text are retained in the source code files. -** The ficl software code is provided on an "as is" basis without -** warranty of any kind, including, without limitation, the implied -** warranties of merchantability and fitness for a particular purpose -** and their equivalents under the laws of any jurisdiction. -** +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** ** I am interested in hearing from anyone who uses ficl. If you have ** a problem, a success story, a defect, an enhancement request, or -** if you would like to contribute to the ficl release (yay!), please -** send me email at the address above. +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** Get the latest Ficl release at http://ficl.sourceforge.net ** -** NOTE: this file depends on sysdep.h for the definition -** of PORTABLE_LONGMULDIV and several abstract types. +** L I C E N S E and D I S C L A I M E R +** +** 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. ** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ -/* $FreeBSD: src/sys/boot/ficl/math64.h,v 1.2 1999/09/29 04:43:06 dcs Exp $ */ -/* $DragonFly: src/sys/boot/ficl/math64.h,v 1.2 2003/06/17 04:28:17 dillon Exp $ */ +/* + * $FreeBSD: src/sys/boot/ficl/math64.h,v 1.4 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/math64.h,v 1.3 2003/11/10 06:08:33 dillon Exp $ + */ #if !defined (__MATH64_H__) #define __MATH64_H__ diff --git a/sys/boot/ficl/prefix.c b/sys/boot/ficl/prefix.c new file mode 100644 index 0000000000..7023980c64 --- /dev/null +++ b/sys/boot/ficl/prefix.c @@ -0,0 +1,202 @@ +/******************************************************************* +** p r e f i x . c +** Forth Inspired Command Language +** Parser extensions for Ficl +** Authors: Larry Hastings & John Sadler (john_sadler@alum.mit.edu) +** Created: April 2001 +** $Id: prefix.c,v 1.6 2001/12/05 07:21:34 jsadler Exp $ +*******************************************************************/ +/* +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** +** I am interested in hearing from anyone who uses ficl. If you have +** a problem, a success story, a defect, an enhancement request, or +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +*/ + +/* + * $FreeBSD: src/sys/boot/ficl/prefix.c,v 1.3 2002/08/31 01:04:53 scottl Exp $ + * $DragonFly: src/sys/boot/ficl/prefix.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include +#include "ficl.h" +#include "math64.h" + +/* +** (jws) revisions: +** A prefix is a word in a dedicated wordlist (name stored in list_name below) +** that is searched in a special way by the prefix parse step. When a prefix +** matches the beginning of an incoming token, push the non-prefix part of the +** token back onto the input stream and execute the prefix code. +** +** The parse step is called ficlParsePrefix. +** Storing prefix entries in the dictionary greatly simplifies +** the process of matching and dispatching prefixes, avoids the +** need to clean up a dynamically allocated prefix list when the system +** goes away, but still allows prefixes to be allocated at runtime. +*/ + +static char list_name[] = ""; + +/************************************************************************** + f i c l P a r s e P r e f i x +** This is the parse step for prefixes - it checks an incoming word +** to see if it starts with a prefix, and if so runs the corrseponding +** code against the remainder of the word and returns true. +**************************************************************************/ +int ficlParsePrefix(FICL_VM *pVM, STRINGINFO si) +{ + int i; + FICL_HASH *pHash; + FICL_WORD *pFW = ficlLookup(pVM->pSys, list_name); + + /* + ** Make sure we found the prefix dictionary - otherwise silently fail + ** If forth-wordlist is not in the search order, we won't find the prefixes. + */ + if (!pFW) + return FICL_FALSE; + + pHash = (FICL_HASH *)(pFW->param[0].p); + /* + ** Walk the list looking for a match with the beginning of the incoming token + */ + for (i = 0; i < (int)pHash->size; i++) + { + pFW = pHash->table[i]; + while (pFW != NULL) + { + int n; + n = pFW->nName; + /* + ** If we find a match, adjust the TIB to give back the non-prefix characters + ** and execute the prefix word. + */ + if (!strincmp(SI_PTR(si), pFW->name, (FICL_UNS)n)) + { + /* (sadler) fixed off-by-one error when the token has no trailing space in the TIB */ + vmSetTibIndex(pVM, si.cp + n - pVM->tib.cp ); + vmExecute(pVM, pFW); + + return (int)FICL_TRUE; + } + pFW = pFW->link; + } + } + + return FICL_FALSE; +} + + +static void tempBase(FICL_VM *pVM, int base) +{ + int oldbase = pVM->base; + STRINGINFO si = vmGetWord0(pVM); + + pVM->base = base; + if (!ficlParseNumber(pVM, si)) + { + int i = SI_COUNT(si); + vmThrowErr(pVM, "%.*s not recognized", i, SI_PTR(si)); + } + + pVM->base = oldbase; + return; +} + +static void fTempBase(FICL_VM *pVM) +{ + int base = stackPopINT(pVM->pStack); + tempBase(pVM, base); + return; +} + +static void prefixHex(FICL_VM *pVM) +{ + tempBase(pVM, 16); +} + +static void prefixTen(FICL_VM *pVM) +{ + tempBase(pVM, 10); +} + + +/************************************************************************** + f i c l C o m p i l e P r e f i x +** Build prefix support into the dictionary and the parser +** Note: since prefixes always execute, they are effectively IMMEDIATE. +** If they need to generate code in compile state you must add +** this code explicitly. +**************************************************************************/ +void ficlCompilePrefix(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + FICL_HASH *pHash; + FICL_HASH *pPrevCompile = dp->pCompile; +#if (FICL_EXTENDED_PREFIX) + FICL_WORD *pFW; +#endif + + /* + ** Create a named wordlist for prefixes to reside in... + ** Since we're doing a special kind of search, make it + ** a single bucket hashtable - hashing does not help here. + */ + pHash = dictCreateWordlist(dp, 1); + pHash->name = list_name; + dictAppendWord(dp, list_name, constantParen, FW_DEFAULT); + dictAppendCell(dp, LVALUEtoCELL(pHash)); + + /* + ** Put __tempbase in the forth-wordlist + */ + dictAppendWord(dp, "__tempbase", fTempBase, FW_DEFAULT); + + /* + ** Temporarily make the prefix list the compile wordlist so that + ** we can create some precompiled prefixes. + */ + dp->pCompile = pHash; + dictAppendWord(dp, "0x", prefixHex, FW_DEFAULT); + dictAppendWord(dp, "0d", prefixTen, FW_DEFAULT); +#if (FICL_EXTENDED_PREFIX) + pFW = ficlLookup(pSys, "\\"); + if (pFW) + { + dictAppendWord(dp, "//", pFW->code, FW_DEFAULT); + } +#endif + dp->pCompile = pPrevCompile; + + return; +} diff --git a/sys/boot/ficl/search.c b/sys/boot/ficl/search.c new file mode 100644 index 0000000000..7f521a9fd1 --- /dev/null +++ b/sys/boot/ficl/search.c @@ -0,0 +1,396 @@ +/******************************************************************* +** s e a r c h . c +** Forth Inspired Command Language +** ANS Forth SEARCH and SEARCH-EXT word-set written in C +** Author: John Sadler (john_sadler@alum.mit.edu) +** Created: 6 June 2000 +** $Id: search.c,v 1.9 2001/12/05 07:21:34 jsadler Exp $ +*******************************************************************/ +/* +** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) +** All rights reserved. +** +** Get the latest Ficl release at http://ficl.sourceforge.net +** +** I am interested in hearing from anyone who uses ficl. If you have +** a problem, a success story, a defect, an enhancement request, or +** if you would like to contribute to the ficl release, please +** contact me by email at the address above. +** +** L I C E N S E and D I S C L A I M E R +** +** 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. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +*/ + +/* + * $FreeBSD: src/sys/boot/ficl/search.c,v 1.2 2002/04/09 17:45:11 dcs Exp $ + * $DragonFly: src/sys/boot/ficl/search.c,v 1.1 2003/11/10 06:08:33 dillon Exp $ + */ + +#include +#include "ficl.h" +#include "math64.h" + +/************************************************************************** + d e f i n i t i o n s +** SEARCH ( -- ) +** Make the compilation word list the same as the first word list in the +** search order. Specifies that the names of subsequent definitions will +** be placed in the compilation word list. Subsequent changes in the search +** order will not affect the compilation word list. +**************************************************************************/ +static void definitions(FICL_VM *pVM) +{ + FICL_DICT *pDict = vmGetDict(pVM); + + assert(pDict); + if (pDict->nLists < 1) + { + vmThrowErr(pVM, "DEFINITIONS error - empty search order"); + } + + pDict->pCompile = pDict->pSearch[pDict->nLists-1]; + return; +} + + +/************************************************************************** + f o r t h - w o r d l i s t +** SEARCH ( -- wid ) +** Return wid, the identifier of the word list that includes all standard +** words provided by the implementation. This word list is initially the +** compilation word list and is part of the initial search order. +**************************************************************************/ +static void forthWordlist(FICL_VM *pVM) +{ + FICL_HASH *pHash = vmGetDict(pVM)->pForthWords; + stackPushPtr(pVM->pStack, pHash); + return; +} + + +/************************************************************************** + g e t - c u r r e n t +** SEARCH ( -- wid ) +** Return wid, the identifier of the compilation word list. +**************************************************************************/ +static void getCurrent(FICL_VM *pVM) +{ + ficlLockDictionary(TRUE); + stackPushPtr(pVM->pStack, vmGetDict(pVM)->pCompile); + ficlLockDictionary(FALSE); + return; +} + + +/************************************************************************** + g e t - o r d e r +** SEARCH ( -- widn ... wid1 n ) +** Returns the number of word lists n in the search order and the word list +** identifiers widn ... wid1 identifying these word lists. wid1 identifies +** the word list that is searched first, and widn the word list that is +** searched last. The search order is unaffected. +**************************************************************************/ +static void getOrder(FICL_VM *pVM) +{ + FICL_DICT *pDict = vmGetDict(pVM); + int nLists = pDict->nLists; + int i; + + ficlLockDictionary(TRUE); + for (i = 0; i < nLists; i++) + { + stackPushPtr(pVM->pStack, pDict->pSearch[i]); + } + + stackPushUNS(pVM->pStack, nLists); + ficlLockDictionary(FALSE); + return; +} + + +/************************************************************************** + s e a r c h - w o r d l i s t +** SEARCH ( c-addr u wid -- 0 | xt 1 | xt -1 ) +** Find the definition identified by the string c-addr u in the word list +** identified by wid. If the definition is not found, return zero. If the +** definition is found, return its execution token xt and one (1) if the +** definition is immediate, minus-one (-1) otherwise. +**************************************************************************/ +static void searchWordlist(FICL_VM *pVM) +{ + STRINGINFO si; + UNS16 hashCode; + FICL_WORD *pFW; + FICL_HASH *pHash = stackPopPtr(pVM->pStack); + + si.count = (FICL_COUNT)stackPopUNS(pVM->pStack); + si.cp = stackPopPtr(pVM->pStack); + hashCode = hashHashCode(si); + + ficlLockDictionary(TRUE); + pFW = hashLookup(pHash, si, hashCode); + ficlLockDictionary(FALSE); + + if (pFW) + { + stackPushPtr(pVM->pStack, pFW); + stackPushINT(pVM->pStack, (wordIsImmediate(pFW) ? 1 : -1)); + } + else + { + stackPushUNS(pVM->pStack, 0); + } + + return; +} + + +/************************************************************************** + s e t - c u r r e n t +** SEARCH ( wid -- ) +** Set the compilation word list to the word list identified by wid. +**************************************************************************/ +static void setCurrent(FICL_VM *pVM) +{ + FICL_HASH *pHash = stackPopPtr(pVM->pStack); + FICL_DICT *pDict = vmGetDict(pVM); + ficlLockDictionary(TRUE); + pDict->pCompile = pHash; + ficlLockDictionary(FALSE); + return; +} + + +/************************************************************************** + s e t - o r d e r +** SEARCH ( widn ... wid1 n -- ) +** Set the search order to the word lists identified by widn ... wid1. +** Subsequently, word list wid1 will be searched first, and word list +** widn searched last. If n is zero, empty the search order. If n is minus +** one, set the search order to the implementation-defined minimum +** search order. The minimum search order shall include the words +** FORTH-WORDLIST and SET-ORDER. A system shall allow n to +** be at least eight. +**************************************************************************/ +static void setOrder(FICL_VM *pVM) +{ + int i; + int nLists = stackPopINT(pVM->pStack); + FICL_DICT *dp = vmGetDict(pVM); + + if (nLists > FICL_DEFAULT_VOCS) + { + vmThrowErr(pVM, "set-order error: list would be too large"); + } + + ficlLockDictionary(TRUE); + + if (nLists >= 0) + { + dp->nLists = nLists; + for (i = nLists-1; i >= 0; --i) + { + dp->pSearch[i] = stackPopPtr(pVM->pStack); + } + } + else + { + dictResetSearchOrder(dp); + } + + ficlLockDictionary(FALSE); + return; +} + + +/************************************************************************** + f i c l - w o r d l i s t +** SEARCH ( -- wid ) +** Create a new empty word list, returning its word list identifier wid. +** The new word list may be returned from a pool of preallocated word +** lists or may be dynamically allocated in data space. A system shall +** allow the creation of at least 8 new word lists in addition to any +** provided as part of the system. +** Notes: +** 1. ficl creates a new single-list hash in the dictionary and returns +** its address. +** 2. ficl-wordlist takes an arg off the stack indicating the number of +** hash entries in the wordlist. Ficl 2.02 and later define WORDLIST as +** : wordlist 1 ficl-wordlist ; +**************************************************************************/ +static void ficlWordlist(FICL_VM *pVM) +{ + FICL_DICT *dp = vmGetDict(pVM); + FICL_HASH *pHash; + FICL_UNS nBuckets; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 1, 1); +#endif + nBuckets = stackPopUNS(pVM->pStack); + pHash = dictCreateWordlist(dp, nBuckets); + stackPushPtr(pVM->pStack, pHash); + return; +} + + +/************************************************************************** + S E A R C H > +** ficl ( -- wid ) +** Pop wid off the search order. Error if the search order is empty +**************************************************************************/ +static void searchPop(FICL_VM *pVM) +{ + FICL_DICT *dp = vmGetDict(pVM); + int nLists; + + ficlLockDictionary(TRUE); + nLists = dp->nLists; + if (nLists == 0) + { + vmThrowErr(pVM, "search> error: empty search order"); + } + stackPushPtr(pVM->pStack, dp->pSearch[--dp->nLists]); + ficlLockDictionary(FALSE); + return; +} + + +/************************************************************************** + > S E A R C H +** ficl ( wid -- ) +** Push wid onto the search order. Error if the search order is full. +**************************************************************************/ +static void searchPush(FICL_VM *pVM) +{ + FICL_DICT *dp = vmGetDict(pVM); + + ficlLockDictionary(TRUE); + if (dp->nLists > FICL_DEFAULT_VOCS) + { + vmThrowErr(pVM, ">search error: search order overflow"); + } + dp->pSearch[dp->nLists++] = stackPopPtr(pVM->pStack); + ficlLockDictionary(FALSE); + return; +} + + +/************************************************************************** + W I D - G E T - N A M E +** ficl ( wid -- c-addr u ) +** Get wid's (optional) name and push onto stack as a counted string +**************************************************************************/ +static void widGetName(FICL_VM *pVM) +{ + FICL_HASH *pHash = vmPop(pVM).p; + char *cp = pHash->name; + FICL_INT len = 0; + + if (cp) + len = strlen(cp); + + vmPush(pVM, LVALUEtoCELL(cp)); + vmPush(pVM, LVALUEtoCELL(len)); + return; +} + +/************************************************************************** + W I D - S E T - N A M E +** ficl ( wid c-addr -- ) +** Set wid's name pointer to the \0 terminated string address supplied +**************************************************************************/ +static void widSetName(FICL_VM *pVM) +{ + char *cp = (char *)vmPop(pVM).p; + FICL_HASH *pHash = vmPop(pVM).p; + pHash->name = cp; + return; +} + + +/************************************************************************** + setParentWid +** FICL +** setparentwid ( parent-wid wid -- ) +** Set WID's link field to the parent-wid. search-wordlist will +** iterate through all the links when finding words in the child wid. +**************************************************************************/ +static void setParentWid(FICL_VM *pVM) +{ + FICL_HASH *parent, *child; +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 2, 0); +#endif + child = (FICL_HASH *)stackPopPtr(pVM->pStack); + parent = (FICL_HASH *)stackPopPtr(pVM->pStack); + + child->link = parent; + return; +} + + +/************************************************************************** + f i c l C o m p i l e S e a r c h +** Builds the primitive wordset and the environment-query namespace. +**************************************************************************/ + +void ficlCompileSearch(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert (dp); + + /* + ** optional SEARCH-ORDER word set + */ + dictAppendWord(dp, ">search", searchPush, FW_DEFAULT); + dictAppendWord(dp, "search>", searchPop, FW_DEFAULT); + dictAppendWord(dp, "definitions", + definitions, FW_DEFAULT); + dictAppendWord(dp, "forth-wordlist", + forthWordlist, FW_DEFAULT); + dictAppendWord(dp, "get-current", + getCurrent, FW_DEFAULT); + dictAppendWord(dp, "get-order", getOrder, FW_DEFAULT); + dictAppendWord(dp, "search-wordlist", + searchWordlist, FW_DEFAULT); + dictAppendWord(dp, "set-current", + setCurrent, FW_DEFAULT); + dictAppendWord(dp, "set-order", setOrder, FW_DEFAULT); + dictAppendWord(dp, "ficl-wordlist", + ficlWordlist, FW_DEFAULT); + + /* + ** Set SEARCH environment query values + */ + ficlSetEnv(pSys, "search-order", FICL_TRUE); + ficlSetEnv(pSys, "search-order-ext", FICL_TRUE); + ficlSetEnv(pSys, "wordlists", FICL_DEFAULT_VOCS); + + dictAppendWord(dp, "wid-get-name", widGetName, FW_DEFAULT); + dictAppendWord(dp, "wid-set-name", widSetName, FW_DEFAULT); + dictAppendWord(dp, "wid-set-super", + setParentWid, FW_DEFAULT); + return; +} + diff --git a/sys/boot/ficl/softwords/classes.fr b/sys/boot/ficl/softwords/classes.fr index 421ab2404c..925a9f26e0 100644 --- a/sys/boot/ficl/softwords/classes.fr +++ b/sys/boot/ficl/softwords/classes.fr @@ -1,12 +1,12 @@ +\ #if (FICL_WANT_OOP) \ ** ficl/softwords/classes.fr \ ** F I C L 2 . 0 C L A S S E S \ john sadler 1 sep 98 \ Needs oop.fr \ -\ $FreeBSD: src/sys/boot/ficl/softwords/classes.fr,v 1.1.6.1 2000/07/06 23:51:46 obrien Exp $ -\ $DragonFly: src/sys/boot/ficl/softwords/classes.fr,v 1.2 2003/06/17 04:28:18 dillon Exp $ +\ $FreeBSD: src/sys/boot/ficl/softwords/classes.fr,v 1.4 2001/04/29 02:36:35 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/classes.fr,v 1.3 2003/11/10 06:08:34 dillon Exp $ -.( loading ficl utility classes ) cr also oop definitions \ REF subclass holds a pointer to an object. It's @@ -39,10 +39,11 @@ end-class object subclass c-4byte 4 chars: .payload - : get drop i@ ; - : set drop i! ; + : get drop q@ ; + : set drop q! ; end-class + object subclass c-cell cell: .payload @@ -105,11 +106,10 @@ object subclass c-ptr ; \ index the pointer in place - : index-ptr ( index inst class -- ) - locals| class inst index | - inst class c-ptr => get-ptr ( addr ) - inst class --> @size index * + ( addr' ) - inst class c-ptr => set-ptr + : index-ptr { index 2:this -- } + this --> get-ptr ( addr ) + this --> @size index * + ( addr' ) + this --> set-ptr ; end-class @@ -129,20 +129,19 @@ c-ptr subclass c-cellPtr end-class -\ ** C - I N T P T R -\ Models a pointer to an int (a 32 bit scalar). +\ ** C - 4 B Y T E P T R +\ Models a pointer to a quadbyte scalar c-ptr subclass c-4bytePtr : @size 2drop 4 ; \ fetch and store through the pointer : get ( inst class -- value ) - c-ptr => get-ptr i@ + c-ptr => get-ptr q@ ; : set ( value inst class -- ) - c-ptr => get-ptr i! + c-ptr => get-ptr q! ; -end-class - - + end-class + \ ** C - 2 B Y T E P T R \ Models a pointer to a 16 bit scalar c-ptr subclass c-2bytePtr @@ -172,3 +171,4 @@ end-class previous definitions +\ #endif diff --git a/sys/boot/ficl/softwords/ficlclass.fr b/sys/boot/ficl/softwords/ficlclass.fr new file mode 100644 index 0000000000..5c10150534 --- /dev/null +++ b/sys/boot/ficl/softwords/ficlclass.fr @@ -0,0 +1,87 @@ +\ #if (FICL_WANT_OOP) +\ ** ficl/softwords/ficlclass.fr +\ Classes to model ficl data structures in objects +\ This is a demo! +\ John Sadler 14 Sep 1998 +\ +\ ** C - W O R D +\ Models a FICL_WORD +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/ficlclass.fr,v 1.1 2002/04/09 17:45:27 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/ficlclass.fr,v 1.1 2003/11/10 06:08:34 dillon Exp $ + +object subclass c-word + c-word ref: .link + c-2byte obj: .hashcode + c-byte obj: .flags + c-byte obj: .nName + c-bytePtr obj: .pName + c-cellPtr obj: .pCode + c-4byte obj: .param0 + + \ Push word's name... + : get-name ( inst class -- c-addr u ) + 2dup + my=[ .pName get-ptr ] -rot + my=[ .nName get ] + ; + + : next ( inst class -- link-inst class ) + my=> .link ; + + : ? + ." c-word: " + 2dup --> get-name type cr + ; + +end-class + +\ ** C - W O R D L I S T +\ Models a FICL_HASH +\ Example of use: +\ get-current c-wordlist --> ref current +\ current --> ? +\ current --> .hash --> ? +\ current --> .hash --> next --> ? + +object subclass c-wordlist + c-wordlist ref: .parent + c-ptr obj: .name + c-cell obj: .size + c-word ref: .hash ( first entry in hash table ) + + : ? + --> get-name ." ficl wordlist " type cr ; + : push drop >search ; + : pop 2drop previous ; + : set-current drop set-current ; + : get-name drop wid-get-name ; + : words { 2:this -- } + this my=[ .size get ] 0 do + i this my=[ .hash index ] ( 2list-head ) + begin + 2dup --> get-name type space + --> next over + 0= until 2drop cr + loop + ; +end-class + +\ : named-wid wordlist postpone c-wordlist metaclass => ref ; + + +\ ** C - F I C L S T A C K +object subclass c-ficlstack + c-4byte obj: .nCells + c-cellPtr obj: .link + c-cellPtr obj: .sp + c-4byte obj: .stackBase + + : init 2drop ; + : ? 2drop + ." ficl stack " cr ; + : top + --> .sp --> .addr --> prev --> get ; +end-class + +\ #endif diff --git a/sys/boot/ficl/softwords/ficllocal.fr b/sys/boot/ficl/softwords/ficllocal.fr index 8a700d318c..d09a2fc96a 100644 --- a/sys/boot/ficl/softwords/ficllocal.fr +++ b/sys/boot/ficl/softwords/ficllocal.fr @@ -8,7 +8,7 @@ \ 1 = found -- \ \ $FreeBSD: src/sys/boot/ficl/softwords/ficllocal.fr,v 1.1 1999/09/29 04:43:15 dcs Exp $ -\ $DragonFly: src/sys/boot/ficl/softwords/ficllocal.fr,v 1.2 2003/06/17 04:28:18 dillon Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/ficllocal.fr,v 1.3 2003/11/10 06:08:34 dillon Exp $ hide 0 constant zero diff --git a/sys/boot/ficl/softwords/fileaccess.fr b/sys/boot/ficl/softwords/fileaccess.fr new file mode 100644 index 0000000000..d8fa6217a4 --- /dev/null +++ b/sys/boot/ficl/softwords/fileaccess.fr @@ -0,0 +1,27 @@ +\ #if FICL_WANT_FILE +\ ** +\ ** File Access words for ficl +\ ** submitted by Larry Hastings, larry@hastings.org +\ ** +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/fileaccess.fr,v 1.1 2002/04/09 17:45:27 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/fileaccess.fr,v 1.1 2003/11/10 06:08:34 dillon Exp $ + +: r/o 1 ; +: r/w 3 ; +: w/o 2 ; +: bin 8 or ; + +: included + r/o bin open-file 0= if + locals| f | end-locals + f include-file + f close-file drop + else + drop + endif + ; + +: include parse-word included ; immediate + +\ #endif diff --git a/sys/boot/ficl/softwords/forml.fr b/sys/boot/ficl/softwords/forml.fr new file mode 100644 index 0000000000..f4189d342e --- /dev/null +++ b/sys/boot/ficl/softwords/forml.fr @@ -0,0 +1,76 @@ +\ examples from FORML conference paper Nov 98 +\ sadler +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/forml.fr,v 1.1 2002/04/09 17:45:27 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/forml.fr,v 1.1 2003/11/10 06:08:34 dillon Exp $ + +.( loading FORML examples ) cr +object --> sub c-example + cell: .cell0 + c-4byte obj: .nCells + 4 c-4byte array: .quad + c-byte obj: .length + 79 chars: .name + + : init ( inst class -- ) + 2dup object => init + s" aardvark" 2swap --> set-name + ; + + : get-name ( inst class -- c-addr u ) + 2dup + --> .name -rot ( c-addr inst class ) + --> .length --> get + ; + + : set-name { c-addr u 2:this -- } + u this --> .length --> set + c-addr this --> .name u move + ; + + : ? ( inst class ) c-example => get-name type cr ; +end-class + + +: test ." this is a test" cr ; +' test +c-word --> ref testref + +\ add a method to c-word... +c-word --> get-wid ficl-set-current +\ list dictionary thread +: list ( inst class ) + begin + 2dup --> get-name type cr + --> next over + 0= until + 2drop +; +set-current + +object subclass c-led + c-byte obj: .state + + : on { led# 2:this -- } + this --> .state --> get + 1 led# lshift or dup !oreg + this --> .state --> set + ; + + : off { led# 2:this -- } + this --> .state --> get + 1 led# lshift invert and dup !oreg + this --> .state --> set + ; + +end-class + + +object subclass c-switch + + : ?on { bit# 2:this -- flag } + + 1 bit# lshift + ; +end-class + diff --git a/sys/boot/ficl/softwords/freebsd.fr b/sys/boot/ficl/softwords/freebsd.fr index 249ba75790..537722b941 100644 --- a/sys/boot/ficl/softwords/freebsd.fr +++ b/sys/boot/ficl/softwords/freebsd.fr @@ -23,7 +23,7 @@ \ ** SUCH DAMAGE. \ ** \ ** $FreeBSD: src/sys/boot/ficl/softwords/freebsd.fr,v 1.4 1999/08/28 00:39:55 peter Exp $ -\ ** $DragonFly: src/sys/boot/ficl/softwords/freebsd.fr,v 1.2 2003/06/17 04:28:18 dillon Exp $ +\ ** $DragonFly: src/sys/boot/ficl/softwords/freebsd.fr,v 1.3 2003/11/10 06:08:34 dillon Exp $ \ Words for use in scripts: \ % ignore errors here diff --git a/sys/boot/ficl/softwords/ifbrack.fr b/sys/boot/ficl/softwords/ifbrack.fr index 556bc7b8c1..f7c0afd885 100644 --- a/sys/boot/ficl/softwords/ifbrack.fr +++ b/sys/boot/ficl/softwords/ifbrack.fr @@ -1,30 +1,23 @@ \ ** ficl/softwords/ifbrack.fr \ ** ANS conditional compile directives [if] [else] [then] \ ** Requires ficl 2.0 or greater... +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/ifbrack.fr,v 1.3 2002/04/09 17:45:27 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/ifbrack.fr,v 1.3 2003/11/10 06:08:34 dillon Exp $ -\ $FreeBSD: src/sys/boot/ficl/softwords/ifbrack.fr,v 1.1 1999/09/29 04:43:16 dcs Exp $ -\ $DragonFly: src/sys/boot/ficl/softwords/ifbrack.fr,v 1.2 2003/06/17 04:28:18 dillon Exp $ - -hidden dup >search ficl-set-current +hide : ?[if] ( c-addr u -- c-addr u flag ) - 2dup 2dup - s" [if]" compare 0= >r - s" [IF]" compare 0= r> - or + 2dup s" [if]" compare-insensitive 0= ; : ?[else] ( c-addr u -- c-addr u flag ) - 2dup 2dup - s" [else]" compare 0= >r - s" [ELSE]" compare 0= r> - or + 2dup s" [else]" compare-insensitive 0= ; : ?[then] ( c-addr u -- c-addr u flag ) - 2dup 2dup - s" [then]" compare 0= >r - s" [THEN]" compare 0= r> + 2dup s" [then]" compare-insensitive 0= >r + 2dup s" [endif]" compare-insensitive 0= r> or ; @@ -53,5 +46,6 @@ set-current 0= if postpone [else] then ; immediate : [then] ( -- ) ; immediate +: [endif] ( -- ) ; immediate previous diff --git a/sys/boot/ficl/softwords/jhlocal.fr b/sys/boot/ficl/softwords/jhlocal.fr index 488815d2c7..23c6963565 100644 --- a/sys/boot/ficl/softwords/jhlocal.fr +++ b/sys/boot/ficl/softwords/jhlocal.fr @@ -12,8 +12,10 @@ \ 3 = found } \ 4 = end of line \ -\ $FreeBSD: src/sys/boot/ficl/softwords/jhlocal.fr,v 1.1.6.1 2000/07/06 23:51:46 obrien Exp $ -\ $DragonFly: src/sys/boot/ficl/softwords/jhlocal.fr,v 1.2 2003/06/17 04:28:18 dillon Exp $ +\ revised 2 June 2000 - { | a -- } now works correctly +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/jhlocal.fr,v 1.4 2001/04/29 02:36:36 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/jhlocal.fr,v 1.3 2003/11/10 06:08:34 dillon Exp $ hide 0 constant zero @@ -25,10 +27,20 @@ hide : ?| ( c-addr u -- c-addr u flag ) 2dup s" |" compare 0= ; -\ examine name and push true if it's a 2local -\ (starts with '2'), false otherwise. -: ?2loc ( c-addr u -- c-addr n flag ) - over c@ [char] 2 = if true else false endif ; +\ examine name - if it's a 2local (starts with "2:"), +\ nibble the prefix (the "2:") off the name and push true. +\ Otherwise push false +\ Problem if the local is named "2:" - we fall off the end... +: ?2loc ( c-addr u -- c-addr u flag ) + over dup c@ [char] 2 = + swap 1+ c@ [char] : = and + if + 2 - swap char+ char+ swap \ dcs/jws: nibble the '2:' + true + else + false + endif +; : ?delim ( c-addr u -- state | c-addr u 0 ) ?| if 2drop 1 exit endif diff --git a/sys/boot/ficl/softwords/marker.fr b/sys/boot/ficl/softwords/marker.fr index c80c2cf3f2..fe6953d07f 100644 --- a/sys/boot/ficl/softwords/marker.fr +++ b/sys/boot/ficl/softwords/marker.fr @@ -2,6 +2,9 @@ \ ** Ficl implementation of CORE EXT MARKER \ John Sadler, 4 Oct 98 \ Requires ficl 2.02 FORGET-WID !! +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/marker.fr,v 1.2 2002/04/09 17:45:27 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/marker.fr,v 1.2 2003/11/10 06:08:34 dillon Exp $ : marker ( "name" -- ) create diff --git a/sys/boot/ficl/softwords/oo.fr b/sys/boot/ficl/softwords/oo.fr index 87f8177300..a90449078f 100644 --- a/sys/boot/ficl/softwords/oo.fr +++ b/sys/boot/ficl/softwords/oo.fr @@ -1,13 +1,12 @@ +\ #if FICL_WANT_OOP \ ** ficl/softwords/oo.fr \ ** F I C L O - O E X T E N S I O N S \ ** john sadler aug 1998 \ -\ $FreeBSD: src/sys/boot/ficl/softwords/oo.fr,v 1.1.6.1 2000/07/06 23:51:46 obrien Exp $ -\ $DragonFly: src/sys/boot/ficl/softwords/oo.fr,v 1.2 2003/06/17 04:28:18 dillon Exp $ +\ $FreeBSD: src/sys/boot/ficl/softwords/oo.fr,v 1.4 2002/04/09 17:45:28 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/oo.fr,v 1.3 2003/11/10 06:08:34 dillon Exp $ - -.( loading ficl O-O extensions ) cr -7 ficl-vocabulary oop +17 ficl-vocabulary oop also oop definitions \ Design goals: @@ -32,8 +31,7 @@ also oop definitions \ A ficl object binds instance storage (payload) to a class. \ object ( -- instance class ) \ All objects push their payload address and class address when -\ executed. All objects have this footprint: -\ cell 0: first payload cell +\ executed. \ A ficl class consists of a parent class pointer, a wordlist \ ID for the methods of the class, and a size for the payload @@ -45,9 +43,40 @@ also oop definitions \ cell 2: size of instance's payload \ Methods expect an object couple ( instance class ) -\ on the stack. +\ on the stack. This is by convention - ficl has no way to +\ police your code to make sure this is always done, but it +\ happens naturally if you use the facilities presented here. +\ \ Overridden methods must maintain the same stack signature as -\ their predecessors. Ficl has no way of enforcing this, though. +\ their predecessors. Ficl has no way of enforcing this, either. +\ +\ Revised Apr 2001 - Added Guy Carver's vtable extensions. Class now +\ has an extra field for the vtable method count. Hasvtable declares +\ refs to vtable classes +\ +\ Revised Nov 2001 - metaclass debug method now finds only metaclass methods +\ +\ Planned: Ficl vtable support +\ Each class has a vtable size parameter +\ END-CLASS allocates and clears the vtable - then it walks class's method +\ list and inserts all new methods into table. For each method, if the table +\ slot is already nonzero, do nothing (overridden method). Otherwise fill +\ vtable slot. Now do same check for parent class vtable, filling only +\ empty slots in the new vtable. +\ Methods are now structured as follows: +\ - header +\ - vtable index +\ - xt +\ :noname definition for code +\ +\ : is redefined to check for override, fill in vtable index, increment method +\ count if not an override, create header and fill in index. Allot code pointer +\ and run :noname +\ ; is overridden to fill in xt returned by :noname +\ --> compiles code to fetch vtable address, offset by index, and execute +\ => looks up xt in the vtable and compiles it directly + + user current-class 0 current-class ! @@ -56,36 +85,49 @@ user current-class \ ** L A T E B I N D I N G \ Compile the method name, and code to find and \ execute it at run-time... -\ parse-method compiles the method name so that it pushes -\ the string base address and count at run-time. \ + +hide + +\ p a r s e - m e t h o d +\ compiles a method name so that it pushes +\ the string base address and count at run-time. + : parse-method \ name run: ( -- c-addr u ) parse-word - postpone sliteral + postpone sliteral ; compile-only -: lookup-method ( class c-addr u -- class xt ) - 2dup - local u - local c-addr - end-locals - 2 pick cell+ @ ( -- class c-addr u wid ) - search-wordlist ( -- class 0 | xt 1 | xt -1 ) - 0= if - c-addr u type ." not found in " - body> >name type +\ l o o k u p - m e t h o d +\ takes a counted string method name from the stack (as compiled +\ by parse-method) and attempts to look this method up in the method list of +\ the class that's on the stack. If successful, it leaves the class on the stack +\ and pushes the xt of the method. If not, it aborts with an error message. + +: lookup-method { class 2:name -- class xt } + name class cell+ @ ( c-addr u wid ) + search-wordlist ( 0 | xt 1 | xt -1 ) + 0= if + name type ." not found in " + class body> >name type cr abort - endif + endif + class swap ; -: exec-method ( instance class c-addr u -- ) - lookup-method execute +: find-method-xt \ name ( class -- class xt ) + parse-word lookup-method ; -: find-method-xt \ name ( class -- class xt ) - parse-word lookup-method +set-current ( stop hiding definitions ) + +: catch-method ( instance class c-addr u -- exc-flag ) + lookup-method catch ; +: exec-method ( instance class c-addr u -- ) + lookup-method execute +; \ Method lookup operator takes a class-addr and instance-addr \ and executes the method from the class's wordlist if @@ -93,12 +135,30 @@ user current-class \ : --> ( instance class -- ??? ) state @ 0= if - find-method-xt execute + find-method-xt execute + else + parse-method postpone exec-method + endif +; immediate + +\ Method lookup with CATCH in case of exceptions +: c-> ( instance class -- ?? exc-flag ) + state @ 0= if + find-method-xt catch else - parse-method postpone exec-method + parse-method postpone catch-method endif ; immediate +\ METHOD makes global words that do method invocations by late binding +\ in case you prefer this style (no --> in your code) +\ Example: everything has next and prev for array access, so... +\ method next +\ method prev +\ my-instance next ( does whatever next does to my-instance by late binding ) + +: method create does> body> >name lookup-method execute ; + \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ ** E A R L Y B I N D I N G @@ -110,8 +170,35 @@ user current-class \ Usage \ my-class get-wid ( -- wid-of-my-class ) \ +1 ficl-named-wordlist instance-vars +instance-vars dup >search ficl-set-current + : => \ c:( class meta -- ) run: ( -- ??? ) invokes compiled method - drop find-method-xt compile, drop + drop find-method-xt compile, drop +; immediate compile-only + +: my=> \ c:( -- ) run: ( -- ??? ) late bind compiled method of current-class + current-class @ dup postpone => +; immediate compile-only + +\ Problem: my=[ assumes that each method except the last is am obj: member +\ which contains its class as the first field of its parameter area. The code +\ detects non-obect members and assumes the class does not change in this case. +\ This handles methods like index, prev, and next correctly, but does not deal +\ correctly with CLASS. +: my=[ \ same as my=> , but binds a chain of methods + current-class @ + begin + parse-word 2dup ( class c-addr u c-addr u ) + s" ]" compare while ( class c-addr u ) + lookup-method ( class xt ) + dup compile, ( class xt ) + dup ?object if \ If object member, get new class. Otherwise assume same class + nip >body cell+ @ ( new-class ) + else + drop ( class ) + endif + repeat 2drop drop ; immediate compile-only @@ -129,12 +216,9 @@ user current-class \ prior state. Note that these words are hidden in their own \ wordlist to prevent accidental use outside a SUB END-CLASS pair. \ -wordlist -dup constant instance-vars -dup >search ficl-set-current : do-instance-var does> ( instance class addr[offset] -- addr[field] ) - nip @ + + nip @ + ; : addr-units: ( offset size "name" -- offset' ) @@ -142,14 +226,14 @@ dup >search ficl-set-current do-instance-var ; -: chars: \ ( offset nCells "name" -- offset' ) Create n char member. +: chars: \ ( offset nCells "name" -- offset' ) Create n char member. chars addr-units: ; -: char: \ ( offset nCells "name" -- offset' ) Create 1 char member. +: char: \ ( offset nCells "name" -- offset' ) Create 1 char member. 1 chars: ; : cells: ( offset nCells "name" -- offset' ) - cells >r aligned r> addr-units: + cells >r aligned r> addr-units: ; : cell: ( offset nCells "name" -- offset' ) @@ -160,17 +244,17 @@ dup >search ficl-set-current \ Example: object obj: m_obj \ : do-aggregate - does> ( instance class pfa -- a-instance a-class ) - 2@ ( inst class a-class a-offset ) - 2swap drop ( a-class a-offset inst ) - + swap ( a-inst a-class ) + objectify + does> ( instance class pfa -- a-instance a-class ) + 2@ ( inst class a-class a-offset ) + 2swap drop ( a-class a-offset inst ) + + swap ( a-inst a-class ) ; -: obj: ( offset class meta "name" -- offset' ) - locals| meta class offset | +: obj: { offset class meta -- offset' } \ "name" create offset , class , - class meta --> get-size offset + - do-aggregate + class meta --> get-size offset + + do-aggregate ; \ Aggregate an array of objects into a class @@ -180,10 +264,10 @@ dup >search ficl-set-current \ named my-array. \ : array: ( offset n class meta "name" -- offset' ) - locals| meta class nobjs offset | - create offset , class , - class meta --> get-size nobjs * offset + - do-aggregate + locals| meta class nobjs offset | + create offset , class , + class meta --> get-size nobjs * offset + + do-aggregate ; \ Aggregate a pointer to an object: REF is a member variable @@ -193,13 +277,35 @@ dup >search ficl-set-current \ in classes.fr. REF is only useful for pre-initialized structures, \ since there's no supported way to set one. : ref: ( offset class meta "name" -- offset' ) - locals| meta class offset | - create offset , class , - offset cell+ - does> ( inst class pfa -- ptr-inst ptr-class ) - 2@ ( inst class ptr-class ptr-offset ) - 2swap drop + @ swap + locals| meta class offset | + create offset , class , + offset cell+ + does> ( inst class pfa -- ptr-inst ptr-class ) + 2@ ( inst class ptr-class ptr-offset ) + 2swap drop + @ swap +; + +\ #if FICL_WANT_VCALL +\ vcall extensions contributed by Guy Carver +: vcall: ( paramcnt "name" -- ) + current-class @ 8 + dup @ dup 1+ rot ! \ Kludge fix to get to .vtCount before it's defined. + create , , \ ( paramcnt index -- ) + does> \ ( inst class pfa -- ptr-inst ptr-class ) + nip 2@ vcall \ ( params offset inst class offset -- ) +; + +: vcallr: 0x80000000 or vcall: ; \ Call with return address desired. + +\ #if FICL_WANT_FLOAT +: vcallf: \ ( paramcnt -- f: r ) + 0x80000000 or + current-class @ 8 + dup @ dup 1+ rot ! \ Kludge fix to get to .vtCount before it's defined. + create , , \ ( paramcnt index -- ) + does> \ ( inst class pfa -- ptr-inst ptr-class ) + nip 2@ vcall f> \ ( params offset inst class offset -- f: r ) ; +\ #endif /* FLOAT */ +\ #endif /* VCALL */ \ END-CLASS terminates construction of a class by storing \ the size of its instance variables in the class's size field @@ -207,9 +313,14 @@ dup >search ficl-set-current \ : end-class ( old-wid addr[size] size -- ) swap ! set-current - search> drop \ pop struct builder wordlist + search> drop \ pop struct builder wordlist ; +\ See resume-class (a metaclass method) below for usage +\ This is equivalent to end-class for now, but that will change +\ when we support vtable bindings. +: suspend-class ( old-wid addr[size] size -- ) end-class ; + set-current previous \ E N D I N S T A N C E V A R I A B L E S @@ -221,7 +332,7 @@ set-current previous \ the wordlist of every class by the SUB method. \ PRECONDITION: current-class contains the class address \ why use a state variable instead of the stack? -\ >> Stack state is not well-defined during compilation (there are +\ >> Stack state is not well-defined during compilation (there are \ >> control structure match codes on the stack, of undefined size \ >> easiest way around this is use of this thread-local variable \ @@ -239,15 +350,21 @@ set-current previous \ See above... \ :noname - wordlist - create + wordlist + create immediate - 0 , \ NULL parent class - dup , \ wid - 3 cells , \ instance size - ficl-set-current - does> dup -; execute metaclass + 0 , \ NULL parent class + dup , \ wid +\ #if FICL_WANT_VCALL + 4 cells , \ instance size +\ #else + 3 cells , \ instance size +\ #endif + ficl-set-current + does> dup +; execute metaclass +\ now brand OBJECT's wordlist (so that ORDER can display it by name) +metaclass drop cell+ @ brand-wordlist metaclass drop current-class ! do-do-instance @@ -263,21 +380,31 @@ create .super ( class metaclass -- parent-class ) create .wid ( class metaclass -- wid ) \ return wid of class 1 cells , do-instance-var -create .size ( class metaclass -- size ) \ return class's payload size +\ #if FICL_WANT_VCALL +create .vtCount \ Number of VTABLE methods, if any 2 cells , do-instance-var -previous +create .size ( class metaclass -- size ) \ return class's payload size + 3 cells , do-instance-var +\ #else +create .size ( class metaclass -- size ) \ return class's payload size + 2 cells , do-instance-var +\ #endif : get-size metaclass => .size @ ; : get-wid metaclass => .wid @ ; : get-super metaclass => .super @ ; +\ #if FICL_WANT_VCALL +: get-vtCount metaclass => .vtCount @ ; +: get-vtAdd metaclass => .vtCount ; +\ #endif \ create an uninitialized instance of a class, leaving \ the address of the new instance and its class \ : instance ( class metaclass "name" -- instance class ) locals| meta parent | - create + create here parent --> .do-instance \ ( inst class ) parent meta metaclass => get-size allot \ allocate payload space @@ -286,10 +413,10 @@ previous \ create an uninitialized array : array ( n class metaclass "name" -- n instance class ) locals| meta parent nobj | - create nobj + create nobj here parent --> .do-instance \ ( nobj inst class ) parent meta metaclass => get-size - nobj * allot \ allocate payload space + nobj * allot \ allocate payload space ; \ create an initialized instance @@ -300,8 +427,8 @@ previous \ create an initialized array of instances : new-array ( n class metaclass "name" -- ) - metaclass => array - --> array-init + metaclass => array + --> array-init ; \ Create an anonymous initialized instance from the heap @@ -322,27 +449,71 @@ previous class ; +\ Create an anonymous initialized instance from the dictionary +: allot { 2:this -- 2:instance } + here ( instance-address ) + this my=> get-size allot + this drop 2dup --> init +; + +\ Create an anonymous array of initialized instances from the dictionary +: allot-array { nobj 2:this -- 2:instance } + here ( instance-address ) + this my=> get-size nobj * allot + this drop 2dup ( 2instance 2instance ) + nobj -rot --> array-init +; + \ create a proxy object with initialized payload address given : ref ( instance-addr class metaclass "name" -- ) drop create , , does> 2@ ; +\ suspend-class and resume-class help to build mutually referent classes. +\ Example: +\ object subclass c-akbar +\ suspend-class ( put akbar on hold while we define jeff ) +\ object subclass c-jeff +\ c-akbar ref: .akbar +\ ( and whatever else comprises this class ) +\ end-class ( done with c-jeff ) +\ c-akbar --> resume-class +\ c-jeff ref: .jeff +\ ( and whatever else goes in c-akbar ) +\ end-class ( done with c-akbar ) +\ +: resume-class { 2:this -- old-wid addr[size] size } + this --> .wid @ ficl-set-current ( old-wid ) + this --> .size dup @ ( old-wid addr[size] size ) + instance-vars >search +; + \ create a subclass +\ This method leaves the stack and search order ready for instance variable +\ building. Pushes the instance-vars wordlist onto the search order, +\ and sets the compilation wordlist to be the private wordlist of the +\ new class. The class's wordlist is deliberately NOT in the search order - +\ to prevent methods from getting used with wrong data. +\ Postcondition: leaves the address of the new class in current-class : sub ( class metaclass "name" -- old-wid addr[size] size ) wordlist - locals| wid meta parent | - parent meta metaclass => get-wid - wid wid-set-super - create immediate - here current-class ! \ prep for do-do-instance - parent , \ save parent class - wid , \ save wid - here parent meta --> get-size dup , ( addr[size] size ) - metaclass => .do-instance - wid ficl-set-current -rot - do-do-instance - instance-vars >search \ push struct builder wordlist + locals| wid meta parent | + parent meta metaclass => get-wid + wid wid-set-super \ set superclass + create immediate \ get the subclass name + wid brand-wordlist \ label the subclass wordlist + here current-class ! \ prep for do-do-instance + parent , \ save parent class + wid , \ save wid +\ #if FICL_WANT_VCALL + parent meta --> get-vtCount , +\ #endif + here parent meta --> get-size dup , ( addr[size] size ) + metaclass => .do-instance + wid ficl-set-current -rot + do-do-instance + instance-vars >search \ push struct builder wordlist ; \ OFFSET-OF returns the offset of an instance variable @@ -354,67 +525,81 @@ previous \ ID returns the string name cell-pair of its class : id ( class metaclass -- c-addr u ) - drop body> >name ; + drop body> >name ; \ list methods of the class : methods \ ( class meta -- ) - locals| meta class | - begin - class body> >name type ." methods:" cr - class meta --> get-wid >search words cr previous - class meta metaclass => get-super - dup to class - 0= until cr + locals| meta class | + begin + class body> >name type ." methods:" cr + class meta --> get-wid >search words cr previous + class meta metaclass => get-super + dup to class + 0= until cr ; \ list class's ancestors : pedigree ( class meta -- ) - locals| meta class | - begin - class body> >name type space - class meta metaclass => get-super - dup to class - 0= until cr + locals| meta class | + begin + class body> >name type space + class meta metaclass => get-super + dup to class + 0= until cr ; -\ decompile a method +\ decompile an instance method : see ( class meta -- ) metaclass => get-wid >search see previous ; -set-current +\ debug a method of metaclass +\ Eg: my-class --> debug my-method +: debug ( class meta -- ) + find-method-xt debug-xt ; + +previous set-current \ E N D M E T A C L A S S -\ META is a nickname for the address of METACLASS... +\ ** META is a nickname for the address of METACLASS... metaclass drop constant meta -\ SUBCLASS is a nickname for a class's SUB method... +\ ** SUBCLASS is a nickname for a class's SUB method... \ Subclass compilation ends when you invoke end-class \ This method is late bound for safety... : subclass --> sub ; +\ #if FICL_WANT_VCALL +\ VTABLE Support extensions (Guy Carver) +\ object --> sub mine hasvtable +: hasvtable 4 + ; immediate +\ #endif + \ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ ** O B J E C T \ Root of all classes :noname - wordlist - create immediate - 0 , \ NULL parent class - dup , \ wid - 0 , \ instance size - ficl-set-current - does> meta + wordlist + create immediate + 0 , \ NULL parent class + dup , \ wid + 0 , \ instance size + ficl-set-current + does> meta ; execute object +\ now brand OBJECT's wordlist (so that ORDER can display it by name) +object drop cell+ @ brand-wordlist object drop current-class ! do-do-instance +instance-vars >search \ O B J E C T M E T H O D S \ Convert instance cell-pair to class cell-pair \ Useful for binding class methods from an instance : class ( instance class -- class metaclass ) - nip meta ; + nip meta ; \ default INIT method zero fills an instance : init ( instance class -- ) @@ -425,26 +610,26 @@ do-do-instance \ Apply INIT to an array of NOBJ objects... \ : array-init ( nobj inst class -- ) - 0 dup locals| &init &next class inst | - \ - \ bind methods outside the loop to save time - \ - class s" init" lookup-method to &init - s" next" lookup-method to &next - drop - 0 ?do - inst class 2dup - &init execute - &next execute drop to inst - loop + 0 dup locals| &init &next class inst | + \ + \ bind methods outside the loop to save time + \ + class s" init" lookup-method to &init + s" next" lookup-method to &next + drop + 0 ?do + inst class 2dup + &init execute + &next execute drop to inst + loop ; \ free storage allocated to a heap instance by alloc or alloc-array \ NOTE: not protected against errors like FREEing something that's \ really in the dictionary. : free \ ( instance class -- ) - drop free - abort" free failed " + drop free + abort" free failed " ; \ Instance aliases for common class methods @@ -453,15 +638,15 @@ do-do-instance meta metaclass => get-super ; : pedigree ( instance class -- ) - object => class + object => class metaclass => pedigree ; : size ( instance class -- sizeof-instance ) - object => class + object => class metaclass => get-size ; : methods ( instance class -- ) - object => class + object => class metaclass => methods ; \ Array indexing methods... @@ -470,30 +655,40 @@ do-do-instance \ obj --> next \ : index ( n instance class -- instance[n] class ) - locals| class inst | - inst class + locals| class inst | + inst class object => class - metaclass => get-size * ( n*size ) - inst + class ; + metaclass => get-size * ( n*size ) + inst + class ; : next ( instance[n] class -- instance[n+1] class ) - locals| class inst | - inst class + locals| class inst | + inst class object => class - metaclass => get-size - inst + - class ; + metaclass => get-size + inst + + class ; : prev ( instance[n] class -- instance[n-1] class ) - locals| class inst | - inst class + locals| class inst | + inst class object => class - metaclass => get-size - inst swap - - class ; + metaclass => get-size + inst swap - + class ; -set-current +: debug ( 2this -- ?? ) + find-method-xt debug-xt ; + +previous set-current \ E N D O B J E C T +\ reset to default search order +only definitions + +\ redefine oop in default search order to put OOP words in the search order and make them +\ the compiling wordlist... + +: oo only also oop definitions ; -previous definitions +\ #endif diff --git a/sys/boot/ficl/softwords/prefix.fr b/sys/boot/ficl/softwords/prefix.fr new file mode 100644 index 0000000000..5c1f3cf65d --- /dev/null +++ b/sys/boot/ficl/softwords/prefix.fr @@ -0,0 +1,60 @@ +\ ** +\ ** Prefix words for ficl +\ ** submitted by Larry Hastings, larry@hastings.org +\ ** +\ (jws) To make a prefix, simply create a new definition in the +\ wordlist. start-prefixes and end-prefixes handle the bookkeeping +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/prefix.fr,v 1.2 2002/04/09 17:45:28 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/prefix.fr,v 1.1 2003/11/10 06:08:34 dillon Exp $ + +variable save-current + +: start-prefixes get-current save-current ! set-current ; +: end-prefixes save-current @ set-current ; +: show-prefixes >search words search> drop ; + +\ #if (FICL_EXTENDED_PREFIX) + +start-prefixes + +\ define " (double-quote) as an alias for s", and make it a prefix +: " postpone s" ; immediate + + +\ make .( a prefix (we just create an alias for it in the prefixes list) +: .( .( ; + + +\ make \ a prefix, and add // (same thing) as a prefix too +\ (jws) "//" is precompiled to save aggravation with Perl +\ : // postpone \ ; immediate + + +\ ** add 0b, 0o, 0d, and 0x as prefixes +\ ** these temporarily shift the base to 2, 8, 10, and 16 respectively +\ ** and consume the next number in the input stream, pushing/compiling +\ ** as normal + +\ (jws) __tempbase is precompiled, as are 0x and 0d - see prefix.c +\ +\ : __tempbase { newbase | oldbase -- } +\ base @ to oldbase +\ newbase base ! +\ 0 0 parse-word >number 2drop drop +\ oldbase base ! +\ ; + +: 0b 2 __tempbase ; immediate + +: 0o 8 __tempbase ; immediate + +\ : 0d 10 __tempbase ; immediate +\ "0d" add-prefix + +\ : 0x 16 __tempbase ; immediate +\ "0x" add-prefix + +end-prefixes + +\ #endif diff --git a/sys/boot/ficl/softwords/softcore.awk b/sys/boot/ficl/softwords/softcore.awk index 29ece6a581..bfa2e05de6 100644 --- a/sys/boot/ficl/softwords/softcore.awk +++ b/sys/boot/ficl/softwords/softcore.awk @@ -10,8 +10,8 @@ # Note! This script uses strftime() which is a gawk-ism, and the # POSIX [[:space:]] character class. # -# $FreeBSD: src/sys/boot/ficl/softwords/softcore.awk,v 1.3.2.2 2001/03/04 04:55:10 obrien Exp $ -# $DragonFly: src/sys/boot/ficl/softwords/softcore.awk,v 1.2 2003/06/17 04:28:18 dillon Exp $ +# $FreeBSD: src/sys/boot/ficl/softwords/softcore.awk,v 1.8 2001/11/03 01:33:12 obrien Exp $ +# $DragonFly: src/sys/boot/ficl/softwords/softcore.awk,v 1.3 2003/11/10 06:08:34 dillon Exp $ BEGIN \ { @@ -129,8 +129,15 @@ END \ { if (commenting) end_comments(); printf " \"quit \";\n"; - printf "\n\nvoid ficlCompileSoftCore(FICL_VM *pVM)\n"; + printf "\n\nvoid ficlCompileSoftCore(FICL_SYSTEM *pSys)\n"; printf "{\n"; - printf " assert(ficlExec(pVM, softWords) != VM_ERREXIT);\n"; + printf " FICL_VM *pVM = pSys->vmList;\n"; + printf " int ret = sizeof (softWords);\n"; + printf " assert(pVM);\n"; + printf "\n" + printf " ret = ficlExec(pVM, softWords);\n"; + printf " if (ret == VM_ERREXIT)\n"; + printf " assert(FALSE);\n"; + printf " return;\n"; printf "}\n"; } diff --git a/sys/boot/ficl/softwords/softcore.fr b/sys/boot/ficl/softwords/softcore.fr index 0eec57171b..df9eeb22a9 100644 --- a/sys/boot/ficl/softwords/softcore.fr +++ b/sys/boot/ficl/softwords/softcore.fr @@ -2,14 +2,13 @@ \ ** FICL soft extensions \ ** John Sadler (john_sadler@alum.mit.edu) \ ** September, 1998 - -\ $FreeBSD: src/sys/boot/ficl/softwords/softcore.fr,v 1.8.2.1 2000/07/06 23:51:46 obrien Exp $ -\ $DragonFly: src/sys/boot/ficl/softwords/softcore.fr,v 1.2 2003/06/17 04:28:18 dillon Exp $ +\ +\ $FreeBSD: src/sys/boot/ficl/softwords/softcore.fr,v 1.12 2002/04/09 17:45:28 dcs Exp $ +\ $DragonFly: src/sys/boot/ficl/softwords/softcore.fr,v 1.3 2003/11/10 06:08:34 dillon Exp $ \ ** Ficl USER variables \ ** See words.c for primitive def'n of USER \ #if FICL_WANT_USER - variable nUser 0 nUser ! : user \ name ( -- ) nUser dup @ user 1 swap +! ; @@ -32,37 +31,39 @@ decimal 32 constant bl : spaces ( n -- ) 0 ?do space loop ; -: abort" +: abort" state @ if postpone if - [char] " parse - postpone sliteral - postpone type + postpone ." postpone cr -2 postpone literal postpone throw postpone endif else - [char] " parse + [char] " parse rot if type cr -2 throw - else - 2drop - then - then + else + 2drop + endif + endif ; immediate \ ** CORE EXT -0 constant false -false invert constant true +0 constant false +false invert constant true : <> = 0= ; : 0<> 0= 0= ; : compile, , ; +: convert char+ 65535 >number drop ; \ cribbed from DPANS A.6.2.0970 : erase ( addr u -- ) 0 fill ; +variable span +: expect ( c-addr u1 -- ) accept span ! ; +\ see marker.fr for MARKER implementation : nip ( y x -- x ) swap drop ; : tuck ( y x -- x y x) swap over ; : within ( test low high -- flag ) over - >r - r> u< ; @@ -99,20 +100,45 @@ false invert constant true ; \ ** SEARCH+EXT words and ficl helpers -\ +\ BRAND-WORDLIST is a helper for ficl-named-wordlist. Usage idiom: +\ wordlist dup create , brand-wordlist +\ gets the name of the word made by create and applies it to the wordlist... +: brand-wordlist ( wid -- ) last-word >name drop wid-set-name ; + +: ficl-named-wordlist \ ( hash-size name -- ) run: ( -- wid ) + ficl-wordlist dup create , brand-wordlist does> @ ; + : wordlist ( -- ) 1 ficl-wordlist ; +\ FICL-SET-CURRENT sets the compile wordlist and pushes the previous value +: ficl-set-current ( wid -- old-wid ) + get-current swap set-current ; + \ DO_VOCABULARY handles the DOES> part of a VOCABULARY \ When executed, new voc replaces top of search stack : do-vocabulary ( -- ) does> @ search> drop >search ; +: ficl-vocabulary ( nBuckets name -- ) + ficl-named-wordlist do-vocabulary ; + : vocabulary ( name -- ) - wordlist create , do-vocabulary ; + 1 ficl-vocabulary ; -: ficl-vocabulary ( nBuckets name -- ) - ficl-wordlist create , do-vocabulary ; +\ PREVIOUS drops the search order stack +: previous ( -- ) search> drop ; + +\ HIDDEN vocabulary is a place to keep helper words from cluttering the namespace +\ USAGE: +\ hide +\ +\ set-current +\