Initial import of libsa, libkern, bootxx, boot.

This commit is contained in:
Evgeniy Ivanov 2012-01-09 18:07:58 +04:00 committed by Ben Gras
parent 972a791882
commit 58a2b0008e
322 changed files with 51780 additions and 518 deletions

View file

@ -1,4 +1,4 @@
MAN= configfile.5 crontab.5 dhcp.conf.5 dir.5 ethers.5 \
MAN= boot.cfg.5 configfile.5 crontab.5 dhcp.conf.5 dir.5 ethers.5 \
fstab.5 hosts.5 httpd.conf.5 http_status.5 keymap.5 \
passwd.5 resolv.conf.5 resolver.5 rhosts.5 statvfs.5 serv.access.5 \
system.conf.5 syslog.conf.5 termcap.5 ttytab.5 TZ.5 tzfile.5 utmp.5 \

247
man/man5/boot.cfg.5 Normal file
View file

@ -0,0 +1,247 @@
.\" $NetBSD: boot.cfg.5,v 1.24 2011/11/28 09:38:45 wiz Exp $
.\"
.\" Copyright (c) 2007 Stephen Borrill
.\" 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. The name of the author 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 ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 28, 2011
.Dt BOOT.CFG 5
.Os
.Sh NAME
.Nm boot.cfg
.Nd configuration file for /boot
.Sh DESCRIPTION
The file
.Pa /boot.cfg
is used to alter the behaviour of the standard boot loader described in
.Xr boot 8 .
Configuration changes include setting the timeout, choosing a console device,
altering the banner text and displaying a menu allowing boot commands to be
easily chosen.
If a
.Nm
file is not present, the system will boot as normal.
.Ss FILE FORMAT
The format of the file is a series of lines containing keyword/value pairs
separated by an equals sign
.Pq Sq = .
There should be no whitespace surrounding the equals sign.
Lines beginning with a hash
.Pq Sq #
are comments and will be ignored.
.Pp
Some keywords can be present multiple times in the file to define additional
items.
Such keywords are noted below.
.Pp
.Bl -tag -width timeout
.It Sy banner
(may be present multiple times)
The text from banner lines is displayed instead of the standard welcome text
by the boot loader.
Up to 10 lines can be defined.
No special character sequences are recognised, so to specify a blank line, a
banner line with no value should be given.
.It Sy clear
If nonzero, clear the screen before printing the banner.
If zero, do not clear the screen (the default).
.It Sy consdev
Changes the console device to that specified in the value.
Valid values are any of those that could be specified at the normal boot
prompt with the consdev command.
.It Sy default
Used to specify the default menu item which will be chosen in the case of
Return being pressed or the timeout timer reaching zero.
The value is the number of the menu item as displayed.
As described above, the menu items are counted from 1 in the order listed in
.Nm .
If not specified, the default value will be option 1, i.e. the first item.
.It Sy format
Changes how the menu options are displayed.
Should be set to one of
.Sq a
for automatic,
.Sq l
for letters and
.Sq n
for numbers.
If set to automatic (the default), menu options will be displayed numerically
unless there are more than 9 options and the timeout is greater than zero.
If there are more than 9 options with a timeout greater than zero and
the format is set to number, only the first 9 options will be available.
.It Sy load
Used to load kernel modules, which will be passed on to the kernel for
initialization during early boot.
The argument is either the complete path and file name of the module to be
loaded, or a symbolic module name.
When the argument is not an absolute path, the boot loader will first
attempt to load
.Pa /stand/\*[Lt]machine\*[Gt]/\*[Lt]kernel_version\*[Gt]/modules/\*[Lt]name\*[Gt]/\*[Lt]name\*[Gt].kmod .
If that file does not exist, it will then attempt to load
.Pa /\*[Lt]name\*[Gt] .
May be used as many times as needed.
.It Sy menu
(may be present multiple times)
Used to define a menu item to be displayed to the end-user at boot time
which allows a series of boot commands to be run without further typing.
The value consists of the required menu text, followed by a colon
.Pq Sq \&:
and then the desired command(s).
Multiple commands can be specified separated by a semi-colon.
If the specified menu text is empty
(the colon appears immediately after the equals sign),
then the displayed menu text is the same as the command.
For example:
.Bd -literal
menu=Boot normally:boot
menu=Boot single-user:boot -s
menu=Boot with module foo:load /foo.kmod;boot
menu=Boot with serial console:consdev com0;boot
menu=:boot hd1a:netbsd -as
.Ed
.Pp
Each menu item will be prefixed by an ascending number when displayed,
i.e. the order in the
.Nm
file is important.
.Pp
Each command is executed just as though the user had typed it in
and so can be any valid command that would be accepted at the
normal boot prompt.
In addition,
.Dq Ic prompt
can be used to drop to the normal boot prompt.
.It Sy timeout
If the value is greater than zero, this specifies the time in seconds
that the boot loader will wait for the end-user to choose a menu item.
During the countdown period, they may press Return to choose the default
option or press a number key corresponding to a menu option.
If any other key is pressed, the countdown will stop and the user will be
prompted to choose a menu option with no further time limit.
If the timeout value is set to zero, the default option will be booted
immediately.
If the timeout value is negative or is not a number, there will be no
time limit for the user to choose an option.
.It Sy userconf
Passes a
.Xr userconf 4
command to the kernel at boot time .
.It Sy rndseed
Takes the path to a random-seed file as written by the
.Fl S
flag to
.Xr rndctl 8
as an argument.
This file is used to seed the kernel entropy pool
.Xr rnd 9
very early in kernel startup, so that high quality randomness is
available to all kernel modules.
This argument should be supplied
before any
.Dq Ic load
commands that may load executable modules.
.El
.Sh EXAMPLES
Here is an example
.Nm
file:
.Bd -literal -offset indent
banner=Welcome to NetBSD
banner==================
banner=
banner=Please choose an option from the following menu:
menu=Boot normally:boot
menu=Boot single-user:boot -s
menu=Boot from second disk:boot hd1a:
menu=Boot with module foo:load /foo.kmod;boot
menu=Boot with modules foo and bar:load /foo.kmod;load /bar.kmod;boot
menu=Boot Xen with 256MB for dom0:load /netbsd-XEN3_DOM0 console=pc;multiboot /usr/pkg/xen3-kernel/xen.gz dom0_mem=256M
menu=Boot Xen with 256MB for dom0 (serial):load /netbsd-XEN3_DOM0 console=com0;multiboot /usr/pkg/xen3-kernel/xen.gz dom0_mem=256M console=com1 com1=115200,8n1
menu=Boot Xen with dom0 in single-user mode:load /netbsd-XEN3_DOM0 -s;multiboot /usr/pkg/xen3-kernel/xen.gz dom0_mem=256M
menu=Go to command line (advanced users only):prompt
clear=1
timeout=-1
default=1
userconf disable ehci*
# Always load ramdisk module
load=/miniroot.kmod
.Ed
.Pp
N.B. Xen counts serial ports from com1 upwards, but
.Nx
counts from com0, so the appropriate device name must be used.
Please see the Xen with serial console example above.
.Pp
This will clear the screen and display:
.Bd -literal -offset indent
Welcome to NetBSD
=================
Please choose an option from the following menu:
1. Boot normally
2. Boot single-user
3. Boot from second disk
4. Boot with module foo
5. Boot with modules foo and bar
6. Boot Xen with 256 MB for dom0
7. Boot Xen with 256 MB for dom0 (serial)
8. Boot Xen with dom0 in single-user mode
9. Go to command line (advanced users only)
Option [1]:
.Ed
.Pp
It will then wait for the user to type 1, 2, 3, 4, 5, 6, 7, 8 or 9 followed by
Return.
Pressing Return by itself will run option 1.
There will be no timeout.
.Sh SEE ALSO
.Xr boot 8 ,
.Xr boothowto 9
.Sh HISTORY
The
.Nm
file appeared in
.Nx 5.0 .
.Sh AUTHORS
The
.Nm
extensions to
.Xr boot 8
were written by
.An Stephen Borrill
.Aq sborrill@NetBSD.org .
.Sh BUGS
Support for
.Nm
is currently for
.Nx Ns /i386
and
.Nx Ns /amd64
only.
It is hoped that its use will be extended to other appropriate ports that
use the
.Xr boot 8
interface.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,14 @@
# $NetBSD: Makefile,v 1.8 2010/05/27 06:58:13 dholland Exp $
SUBDIR= biosboot
LIBOBJ= ${.OBJDIR}
.MAKEOVERRIDES+= LIBOBJ
.include <bsd.subdir.mk>
.include <bsd.obj.mk>
cleandir distclean: .WAIT cleanlibdir
cleanlibdir:
-rm -rf lib

View file

@ -0,0 +1,171 @@
# $NetBSD: Makefile.boot,v 1.56 2011/12/25 06:09:09 tsutsui Exp $
S= ${.CURDIR}/../../../../..
NOMAN=
PROG?= boot
NEWVERSWHAT?= "BIOS Boot"
VERSIONFILE?= ${.CURDIR}/../version
AFLAGS.biosboot.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
SOURCES?= biosboot.S boot2.c conf.c devopen.c exec.c
SRCS= ${SOURCES}
.if !make(depend)
SRCS+= vers.c
.endif
PIE_CFLAGS=
PIE_AFLAGS=
PIE_LDFLAGS=
.include <bsd.own.mk>
STRIPFLAG= # nothing
LIBCRT0= # nothing
LIBCRTBEGIN= # nothing
LIBCRTEND= # nothing
LIBC= # nothing
BINDIR=/usr/mdec
BINMODE=444
.PATH: ${.CURDIR}/.. ${.CURDIR}/../../lib
LDFLAGS+= -nostdlib -Wl,-N -Wl,-e,boot_start
CPPFLAGS+= -I ${.CURDIR}/.. -I ${.CURDIR}/../../lib -I ${S}/lib/libsa
CPPFLAGS+= -I ${.OBJDIR}
# Make sure we override any optimization options specified by the user
COPTS= -Os
.if defined(HAVE_GCC)
.if ${MACHINE_ARCH} == "x86_64"
LDFLAGS+= -Wl,-m,elf_i386
AFLAGS+= -m32
CPUFLAGS= -m32
LIBKERN_ARCH=i386
KERNMISCMAKEFLAGS="LIBKERN_ARCH=i386"
.else
CPUFLAGS= -march=i386 -mtune=i386
.endif
.endif
CFLAGS+= -mno-sse -mno-sse2 -mno-sse3
COPTS+= -ffreestanding
CFLAGS+= -Wall -Wmissing-prototypes -Wstrict-prototypes
CPPFLAGS+= -nostdinc -D_STANDALONE
CPPFLAGS+= -I$S
CPPFLAGS+= -DSUPPORT_PS2
CPPFLAGS+= -DDIRECT_SERIAL
CPPFLAGS+= -DSUPPORT_SERIAL=boot_params.bp_consdev
CPPFLAGS+= -DCONSPEED=boot_params.bp_conspeed
CPPFLAGS+= -DCONSADDR=boot_params.bp_consaddr
CPPFLAGS+= -DCONSOLE_KEYMAP=boot_params.bp_keymap
CPPFLAGS+= -DSUPPORT_CD9660
CPPFLAGS+= -DSUPPORT_USTARFS
CPPFLAGS+= -DSUPPORT_DOSFS
CPPFLAGS+= -DSUPPORT_EXT2FS
CPPFLAGS+= -DSUPPORT_MINIXFS3
CPPFLAGS+= -DPASS_BIOSGEOM
CPPFLAGS+= -DPASS_MEMMAP
#CPPFLAGS+= -DBOOTPASSWD
CPPFLAGS+= -DEPIA_HACK
#CPPFLAGS+= -DDEBUG_MEMSIZE
#CPPFLAGS+= -DBOOT_MSG_COM0
CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
# The biosboot code is linked to 'virtual' address of zero and is
# loaded at physical address 0x10000.
# XXX The heap values should be determined from _end.
SAMISCCPPFLAGS+= -DHEAP_START=0x40000 -DHEAP_LIMIT=0x70000
SAMISCCPPFLAGS+= -DLIBSA_PRINTF_LONGLONG_SUPPORT
SAMISCMAKEFLAGS+= SA_USE_CREAD=yes # Read compressed kernels
SAMISCMAKEFLAGS+= SA_INCLUDE_NET=no # Netboot via TFTP, NFS
.if defined(HAVE_GCC) || defined(HAVE_PCC)
CPPFLAGS+= -Wno-pointer-sign
.endif
# CPPFLAGS+= -DBOOTXX_RAID1_SUPPORT
I386_STAND_DIR?= $S/arch/i386/stand
CLEANFILES+= machine x86
.if !make(obj) && !make(clean) && !make(cleandir)
.BEGIN:
-rm -f machine && ln -s $S/arch/i386/include machine
-rm -f x86 && ln -s $S/arch/x86/include x86
.ifdef LIBOBJ
-rm -f lib && ln -s ${LIBOBJ}/lib lib
mkdir -p ${LIBOBJ}/lib
.endif
.endif
### find out what to use for libi386
I386DIR= ${I386_STAND_DIR}/lib
.include "${I386DIR}/Makefile.inc"
LIBI386= ${I386LIB}
### find out what to use for libsa
SA_AS= library
SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes"
SAMISCMAKEFLAGS+="SA_ENABLE_LS_OP=yes"
.include "${S}/lib/libsa/Makefile.inc"
LIBSA= ${SALIB}
### find out what to use for libkern
KERN_AS= library
.include "${S}/lib/libkern/Makefile.inc"
LIBKERN= ${KERNLIB}
### find out what to use for libz
Z_AS= library
.include "${S}/lib/libz/Makefile.inc"
LIBZ= ${ZLIB}
cleandir distclean: .WAIT cleanlibdir
cleanlibdir:
-rm -rf lib
LIBLIST= ${LIBI386} ${LIBSA} ${LIBZ} ${LIBKERN} ${LIBI386} ${LIBSA}
# LIBLIST= ${LIBSA} ${LIBKERN} ${LIBI386} ${LIBSA} ${LIBZ} ${LIBKERN}
CLEANFILES+= ${PROG}.tmp ${PROG}.map ${PROG}.syms vers.c
vers.c: ${VERSIONFILE} ${SOURCES} ${LIBLIST} ${.CURDIR}/../Makefile.boot
${HOST_SH} ${S}/conf/newvers_stand.sh ${VERSIONFILE} x86 ${NEWVERSWHAT}
# Anything that calls 'real_to_prot' must have a %pc < 0x10000.
# We link the program, find the callers (all in libi386), then
# explicitly pull in the required objects before any other library code.
${PROG}: ${OBJS} ${LIBLIST} ${.CURDIR}/../Makefile.boot
${_MKTARGET_LINK}
bb="$$( ${CC} -o ${PROG}.syms ${LDFLAGS} -Wl,-Ttext,0 -Wl,-cref \
${OBJS} ${LIBLIST} | ( \
while read symbol file; do \
[ -z "$$file" ] && continue; \
[ "$$symbol" = real_to_prot ] && break; \
done; \
while \
oifs="$$IFS"; \
IFS='()'; \
set -- $$file; \
IFS="$$oifs"; \
[ -n "$$2" ] && echo "${I386DST}/$$2"; \
read file rest && [ -z "$$rest" ]; \
do :; \
done; \
) )"; \
${CC} -o ${PROG}.syms ${LDFLAGS} -Wl,-Ttext,0 \
-Wl,-Map,${PROG}.map -Wl,-cref ${OBJS} $$bb ${LIBLIST}
${OBJCOPY} -O binary ${PROG}.syms ${PROG}
.include <bsd.prog.mk>

View file

@ -0,0 +1,149 @@
/* $NetBSD: biosboot.S,v 1.8 2011/01/05 23:13:01 jakllsch Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
#include <sys/bootblock.h>
/*
* Code linked to 0x1000:0 and (usually) read from /boot by bootxx code
*
* On entry:
* %dl BIOS drive number
* %ecx:%ebx Sector number of NetBSD partition
* %ds:%si Boot parameter block (patched by installboot)
* %cs 0x1000
* %ds, %es, %ss All zero
* %sp near 0xfffc
*/
.text
.code16
ENTRY(boot_start)
jmp boot_start_1
.balign 4
ENTRY(boot_magic)
.long X86_BOOT_MAGIC_2 /* checked for by bootxx code */
ENTRY(boot_params)
.long boot_start_1 - boot_params
#include <boot_params.S>
. = boot_start + 0x80 /* space for patchable variables */
boot_start_1:
#if 0
/* Allow for boot_start not being %cs:0 */
call 2f
2: pop %cx
sub $2b, %cx /* %ax is offset */
test $0xf, %cx /* check code seg aligned */
jz 3f
lret /* not playing if not */
3: mov %cs, %ax
shr $4, %cx
add %cx, %ax /* segment staring at boot_start */
push %ax
push $4f
lret
4:
#endif
mov %cs, %ax
mov %ax, %es
movl %ecx, %ebp /* move LBA out of the way */
/* Grab boot_params patched into bootxx by installboot */
cmpl $X86_BOOT_MAGIC_1,-4(%si) /* sanity check ptr */
jne 2f
mov $boot_params, %di
movl (%si),%ecx
cmp $boot_start_1 - boot_params, %cx
jbe 1f
mov $boot_start_1 - boot_params, %cx
1: cld
rep
movsb
2:
mov %ax, %ds
movl $_end, %eax /* top of bss */
shr $4, %eax /* as a segment */
add $0x1001, %ax /* and + 64k */
mov %ax, %ss /* for stack */
mov $0xfffc, %sp /* %sp at top of it */
call gdt_fixup
calll real_to_prot
.code32
movl $_end, %ecx /* zero bss */
movl $__bss_start, %edi
subl %edi, %ecx
shr $2, %ecx /* _end and __bss_start are aligned */
xor %eax, %eax
rep
stosl
testb $X86_BP_FLAGS_LBA64VALID, boot_params+4
jnz 1f
xorl %ebp, %ebp /* high part of LBA is not valid */
1:
movzbl %dl, %edx
push %ebp /* high 32 bits of first sector */
push %ebx /* first sector of bios partition */
push %edx /* bios disk */
call _C_LABEL(boot2) /* C bootstrap code */
addl $12, %esp
call prot_to_real
.code16
boot_fail:
push %ax
movw $1f, %si
call message
pop %si
call message
jmp loopstop
1: .asciz "Boot2 failed: "
ENTRY(_rtt)
.code32
call prot_to_real
.code16
loopstop:
movb $0x86, %ah /* delay for about a second */
movw $16, %cx
int $0x15
int $0x18 /* might be a boot fail entry */
1: sti
hlt
jmp 1b

View file

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.3 2005/12/11 12:17:48 christos Exp $
PROG= boot
.include <../Makefile.boot>

View file

@ -0,0 +1,522 @@
/* $NetBSD: boot2.c,v 1.57 2011/12/25 06:09:09 tsutsui Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 2003
* David Laight. All rights reserved
* Copyright (c) 1996, 1997, 1999
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996, 1997
* Perry E. Metzger. All rights reserved.
* Copyright (c) 1997
* Jason R. Thorpe. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Matthias Drochner.
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Based on stand/biosboot/main.c */
#include <sys/types.h>
#include <sys/reboot.h>
#include <sys/bootblock.h>
#include <lib/libsa/stand.h>
#include <lib/libsa/ufs.h>
#include <lib/libkern/libkern.h>
#include <libi386.h>
#include <bootmod.h>
#include <bootmenu.h>
#include <vbe.h>
#include "devopen.h"
#ifdef SUPPORT_PS2
#include <biosmca.h>
#endif
extern struct x86_boot_params boot_params;
extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[];
int errno;
int boot_biosdev;
daddr_t boot_biossector;
static const char * const names[][2] = {
{ "netbsd", "netbsd.gz" },
{ "onetbsd", "onetbsd.gz" },
{ "netbsd.old", "netbsd.old.gz" },
};
#define NUMNAMES (sizeof(names)/sizeof(names[0]))
#define DEFFILENAME names[0][0]
#define MAXDEVNAME 16
static char *default_devname;
static int default_unit, default_partition;
static const char *default_filename;
char *sprint_bootsel(const char *);
void bootit(const char *, int, int);
void print_banner(void);
void boot2(int, uint64_t);
void command_help(char *);
void command_ls(char *);
void command_quit(char *);
void command_boot(char *);
void command_dev(char *);
void command_consdev(char *);
void command_modules(char *);
void command_multiboot(char *);
const struct bootblk_command commands[] = {
{ "help", command_help },
{ "?", command_help },
{ "ls", command_ls },
{ "quit", command_quit },
{ "boot", command_boot },
{ "dev", command_dev },
{ "consdev", command_consdev },
{ "modules", command_modules },
{ "load", module_add },
{ "multiboot", command_multiboot },
{ "vesa", command_vesa },
{ "splash", splash_add },
{ "rndseed", rnd_add },
{ "userconf", userconf_add },
{ NULL, NULL },
};
int
parsebootfile(const char *fname, char **fsname, char **devname,
int *unit, int *partition, const char **file)
{
const char *col;
*fsname = "ufs";
*devname = default_devname;
*unit = default_unit;
*partition = default_partition;
*file = default_filename;
if (fname == NULL)
return 0;
if ((col = strchr(fname, ':')) != NULL) { /* device given */
static char savedevname[MAXDEVNAME+1];
int devlen;
int u = 0, p = 0;
int i = 0;
devlen = col - fname;
if (devlen > MAXDEVNAME)
return EINVAL;
#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
if (!isvalidname(fname[i]))
return EINVAL;
do {
savedevname[i] = fname[i];
i++;
} while (isvalidname(fname[i]));
savedevname[i] = '\0';
#define isnum(c) ((c) >= '0' && (c) <= '9')
if (i < devlen) {
if (!isnum(fname[i]))
return EUNIT;
do {
u *= 10;
u += fname[i++] - '0';
} while (isnum(fname[i]));
}
#define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
if (i < devlen) {
if (!isvalidpart(fname[i]))
return EPART;
p = fname[i++] - 'a';
}
if (i != devlen)
return ENXIO;
*devname = savedevname;
*unit = u;
*partition = p;
fname = col + 1;
}
if (*fname)
*file = fname;
return 0;
}
char *
sprint_bootsel(const char *filename)
{
char *fsname, *devname;
int unit, partition;
const char *file;
static char buf[80];
if (parsebootfile(filename, &fsname, &devname, &unit,
&partition, &file) == 0) {
sprintf(buf, "%s%d%c:%s", devname, unit, 'a' + partition, file);
return buf;
}
return "(invalid)";
}
static void
clearit(void)
{
if (bootconf.clear)
clear_pc_screen();
}
void
bootit(const char *filename, int howto, int tell)
{
if (tell) {
printf("booting %s", sprint_bootsel(filename));
if (howto)
printf(" (howto 0x%x)", howto);
printf("\n");
}
if (exec_netbsd(filename, 0, howto, boot_biosdev < 0x80, clearit) < 0)
printf("boot: %s: %s\n", sprint_bootsel(filename),
strerror(errno));
else
printf("boot returned\n");
}
void
print_banner(void)
{
clearit();
#ifndef SMALL
int n;
if (bootconf.banner[0]) {
for (n = 0; bootconf.banner[n] && n < MAXBANNER; n++)
printf("%s\n", bootconf.banner[n]);
} else {
#endif /* !SMALL */
printf("\n"
">> %s, Revision %s (from NetBSD %s)\n"
">> Memory: %d/%d k\n",
bootprog_name, bootprog_rev, bootprog_kernrev,
getbasemem(), getextmem());
#ifndef SMALL
}
#endif /* !SMALL */
}
/*
* Called from the initial entry point boot_start in biosboot.S
*
* biosdev: BIOS drive number the system booted from
* biossector: Sector number of the NetBSD partition
*/
void
boot2(int biosdev, uint64_t biossector)
{
extern char twiddle_toggle;
int currname;
char c;
twiddle_toggle = 1; /* no twiddling until we're ready */
initio(boot_params.bp_consdev);
#ifdef SUPPORT_PS2
biosmca();
#endif
gateA20();
boot_modules_enabled = !(boot_params.bp_flags
& X86_BP_FLAGS_NOMODULES);
if (boot_params.bp_flags & X86_BP_FLAGS_RESET_VIDEO)
biosvideomode();
vbe_init();
/* need to remember these */
boot_biosdev = biosdev;
boot_biossector = biossector;
/* try to set default device to what BIOS tells us */
bios2dev(biosdev, biossector, &default_devname, &default_unit,
&default_partition);
/* if the user types "boot" without filename */
default_filename = DEFFILENAME;
#ifndef SMALL
if (!(boot_params.bp_flags & X86_BP_FLAGS_NOBOOTCONF)) {
parsebootconf(BOOTCONF);
} else {
bootconf.timeout = boot_params.bp_timeout;
}
/*
* If console set in boot.cfg, switch to it.
* This will print the banner, so we don't need to explicitly do it
*/
if (bootconf.consdev)
command_consdev(bootconf.consdev);
else
print_banner();
/* Display the menu, if applicable */
twiddle_toggle = 0;
if (bootconf.nummenu > 0) {
/* Does not return */
doboottypemenu();
}
#else
twiddle_toggle = 0;
print_banner();
#endif
printf("Press return to boot now, any other key for boot menu\n");
for (currname = 0; currname < NUMNAMES; currname++) {
printf("booting %s - starting in ",
sprint_bootsel(names[currname][0]));
#ifdef SMALL
c = awaitkey(boot_params.bp_timeout, 1);
#else
c = awaitkey((bootconf.timeout < 0) ? 0 : bootconf.timeout, 1);
#endif
if ((c != '\r') && (c != '\n') && (c != '\0')) {
if ((boot_params.bp_flags & X86_BP_FLAGS_PASSWORD) == 0) {
/* do NOT ask for password */
bootmenu(); /* does not return */
} else {
/* DO ask for password */
if (check_password((char *)boot_params.bp_password)) {
/* password ok */
printf("type \"?\" or \"help\" for help.\n");
bootmenu(); /* does not return */
} else {
/* bad password */
printf("Wrong password.\n");
currname = 0;
continue;
}
}
}
/*
* try pairs of names[] entries, foo and foo.gz
*/
/* don't print "booting..." again */
bootit(names[currname][0], 0, 0);
/* since it failed, try compressed bootfile. */
bootit(names[currname][1], 0, 1);
}
bootmenu(); /* does not return */
}
/* ARGSUSED */
void
command_help(char *arg)
{
printf("commands are:\n"
"boot [xdNx:][filename] [-12acdqsvxz]\n"
" (ex. \"hd0a:netbsd.old -s\"\n"
"ls [path]\n"
"dev xd[N[x]]:\n"
"consdev {pc|com[0123]|com[0123]kbd|auto}\n"
"vesa {modenum|on|off|enabled|disabled|list}\n"
"modules {on|off|enabled|disabled}\n"
"load {path_to_module}\n"
"multiboot [xdNx:][filename] [<args>]\n"
"userconf {command}\n"
"rndseed {path_to_rndseed_file}\n"
"help|?\n"
"quit\n");
}
void
command_ls(char *arg)
{
const char *save = default_filename;
default_filename = "/";
ls(arg);
default_filename = save;
}
/* ARGSUSED */
void
command_quit(char *arg)
{
printf("Exiting...\n");
delay(1000000);
reboot();
/* Note: we shouldn't get to this point! */
panic("Could not reboot!");
}
void
command_boot(char *arg)
{
char *filename;
int howto;
if (parseboot(arg, &filename, &howto))
bootit(filename, howto, (howto & AB_VERBOSE) != 0);
}
void
command_dev(char *arg)
{
static char savedevname[MAXDEVNAME + 1];
char *fsname, *devname;
const char *file; /* dummy */
if (*arg == '\0') {
biosdisk_probe();
printf("default %s%d%c\n", default_devname, default_unit,
'a' + default_partition);
return;
}
if (strchr(arg, ':') == NULL ||
parsebootfile(arg, &fsname, &devname, &default_unit,
&default_partition, &file)) {
command_help(NULL);
return;
}
/* put to own static storage */
strncpy(savedevname, devname, MAXDEVNAME + 1);
default_devname = savedevname;
}
static const struct cons_devs {
const char *name;
u_int tag;
} cons_devs[] = {
{ "pc", CONSDEV_PC },
{ "com0", CONSDEV_COM0 },
{ "com1", CONSDEV_COM1 },
{ "com2", CONSDEV_COM2 },
{ "com3", CONSDEV_COM3 },
{ "com0kbd", CONSDEV_COM0KBD },
{ "com1kbd", CONSDEV_COM1KBD },
{ "com2kbd", CONSDEV_COM2KBD },
{ "com3kbd", CONSDEV_COM3KBD },
{ "auto", CONSDEV_AUTO },
{ NULL, 0 }
};
void
command_consdev(char *arg)
{
const struct cons_devs *cdp;
for (cdp = cons_devs; cdp->name; cdp++) {
if (strcmp(arg, cdp->name) == 0) {
initio(cdp->tag);
print_banner();
return;
}
}
printf("invalid console device.\n");
}
void
command_modules(char *arg)
{
if (strcmp(arg, "enabled") == 0 ||
strcmp(arg, "on") == 0)
boot_modules_enabled = true;
else if (strcmp(arg, "disabled") == 0 ||
strcmp(arg, "off") == 0)
boot_modules_enabled = false;
else
printf("invalid flag, must be 'enabled' or 'disabled'.\n");
}
void
command_multiboot(char *arg)
{
char *filename;
filename = arg;
if (exec_multiboot(filename, gettrailer(arg)) < 0)
printf("multiboot: %s: %s\n", sprint_bootsel(filename),
strerror(errno));
else
printf("boot returned\n");
}

View file

@ -0,0 +1,79 @@
/* $NetBSD: conf.c,v 1.5 2008/04/05 18:21:34 tsutsui Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <lib/libsa/stand.h>
#include <lib/libsa/ufs.h>
#include <lib/libsa/lfs.h>
#ifdef SUPPORT_EXT2FS
#include <lib/libsa/ext2fs.h>
#endif
#ifdef SUPPORT_MINIXFS3
#include <lib/libsa/minixfs3.h>
#endif
#ifdef SUPPORT_USTARFS
#include <lib/libsa/ustarfs.h>
#endif
#ifdef SUPPORT_DOSFS
#include <lib/libsa/dosfs.h>
#endif
#ifdef SUPPORT_CD9660
#include <lib/libsa/cd9660.h>
#endif
#include <biosdisk.h>
struct devsw devsw[] = {
{"disk", biosdisk_strategy, biosdisk_open, biosdisk_close,
biosdisk_ioctl},
};
int ndevs = sizeof(devsw) / sizeof(struct devsw);
struct fs_ops file_system[] = {
#ifdef SUPPORT_CD9660
FS_OPS(cd9660),
#endif
#ifdef SUPPORT_USTARFS
FS_OPS(ustarfs),
#endif
FS_OPS(ffsv1), FS_OPS(ffsv2),
FS_OPS(lfsv1), FS_OPS(lfsv2),
#ifdef SUPPORT_EXT2FS
FS_OPS(ext2fs),
#endif
#ifdef SUPPORT_MINIXFS3
FS_OPS(minixfs3),
#endif
#ifdef SUPPORT_DOSFS
FS_OPS(dosfs),
#endif
};
int nfsys = sizeof(file_system) / sizeof(struct fs_ops);

View file

@ -0,0 +1,146 @@
/* $NetBSD: devopen.c,v 1.8 2010/12/24 20:40:42 jakllsch Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Bang Jun-Young.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 1996, 1997
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <libi386.h>
#include <biosdisk.h>
#include "devopen.h"
#ifdef _STANDALONE
#include <bootinfo.h>
#endif
#ifdef SUPPORT_PS2
#include <biosmca.h>
#endif
static int dev2bios(char *, int, int *);
static int
dev2bios(char *devname, int unit, int *biosdev)
{
if (strcmp(devname, "hd") == 0)
*biosdev = 0x80 + unit;
else if (strcmp(devname, "fd") == 0)
*biosdev = 0x00 + unit;
else if (strcmp(devname, "cd") == 0)
*biosdev = boot_biosdev;
else
return ENXIO;
return 0;
}
void
bios2dev(int biosdev, daddr_t sector, char **devname, int *unit, int *partition)
{
/* set default */
*unit = biosdev & 0x7f;
if (biosdev & 0x80) {
/*
* There seems to be no standard way of numbering BIOS
* CD-ROM drives. The following method is a little tricky
* but works nicely.
*/
if (biosdev >= 0x80 + get_harddrives()) {
*devname = "cd";
*unit = 0; /* override default */
} else
*devname = "hd";
} else
*devname = "fd";
*partition = biosdisk_findpartition(biosdev, sector);
}
#ifdef _STANDALONE
struct btinfo_bootpath bibp;
extern bool kernel_loaded;
#endif
/*
* Open the BIOS disk device
*/
int
devopen(struct open_file *f, const char *fname, char **file)
{
char *fsname, *devname;
int unit, partition;
int biosdev;
int error;
if ((error = parsebootfile(fname, &fsname, &devname,
&unit, &partition, (const char **) file))
|| (error = dev2bios(devname, unit, &biosdev)))
return error;
f->f_dev = &devsw[0]; /* must be biosdisk */
#ifdef _STANDALONE
if (!kernel_loaded) {
strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath));
BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
}
#endif
return biosdisk_open(f, biosdev, partition);
}

View file

@ -0,0 +1,5 @@
/* $NetBSD: devopen.h,v 1.4 2010/12/24 20:40:42 jakllsch Exp $ */
extern int boot_biosdev;
void bios2dev(int, daddr_t, char **, int *, int *);

View file

@ -0,0 +1,49 @@
$NetBSD: version,v 1.15 2011/02/09 04:37:54 jmcneill Exp $
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important - make sure the entries are appended on end, last item
is taken as the current.
2.0: Change over to Matthias Drochner's two-stage boot system.
All code is completely new.
2.1: New welcoming banner.
2.2: Use common menu / parsing functions with other bootloaders.
New framework to pass information to the kernel.
2.3: Switch to new NetBSD MBR partition ID.
2.4: Support BIOS Int13-Extensions.
2.5: Support ustarfs boot.
2.6: Support ELF boot.
2.7: Support on-the-fly switching of console devices.
2.8: Support verbose/quiet boot.
2.9: Recognize PS/2 L40 at runtime and use appropriate gate A20
initialization (rather than using a compile flag).
Recognize ESDI disks and identify them as ed(4) for COMPAT_OLDBOOT.
2.10: g/c COMPAT_OLDBOOT.
2.11: loadfile() update: ELF symbols no longer need backward seeks.
2.12: loadfile() update to avoid backwards seeks for ELF Program Headers.
2.13: Support boot from 1.44MB floppies in 2.88MB floppy drives.
2.14: Add a quirk for BIOSes which report extended memory size
in slightly nonstandard way in int15, function 0xE801.
2.15: Use int15/0xc7 to get memory information on machines which support
it, like later IBM PS/2 machines.
2.16: Move 16bit %ss to allow >64k for code, data and stack.
Default partition to that passed in by mbr code.
Support limited filename globbing in 'ls' command.
Use .code16 and .code32 directives
3.0: Separate out into bootxx and boot
3.1: Rename to /usr/mdec/boot.
Leave space in bootxx for FAT32 BPB and MBR partition table.
Keep MBR's existing BPB and partition table when installing bootxx.
3.2: Add support for passing boot wedge information to the kernel.
3.3: Add support for cd9660 file system.
5.0: Support for boot menu, modules.
5.1: Change boot messages to replace build date with kernel version.
5.2: Support for multiboot.
5.3: Autoload kernel module for root file system.
5.4: The VESA VBE mode number is now passed to the kernel so it can be
restored on ACPI resume.
5.5: Adjust stack and heap areas to not overlap.
5.6: GUID Partition Table support.
5.7: Recognize 64-bit LBA from bootxx.
5.8: Support for splash images.
5.9: VESA VBE/DDC EDID support.

View file

@ -0,0 +1,21 @@
# $NetBSD: Makefile,v 1.14 2010/12/29 17:44:03 jakllsch Exp $
SUBDIR= bootxx_ffsv1 .WAIT bootxx_ffsv2 bootxx_lfsv1 bootxx_lfsv2
SUBDIR+=bootxx_msdos bootxx_ustarfs
# Ext2fs doesn't have enough free space (it has only 1KB)
# to store this primary bootloader, but we can put it into
# an independent small 'boot' partition as NetBSD/hp300 does.
SUBDIR+=bootxx_ext2fs
SUBDIR+=bootxx_minixfs3
LIBOBJ= ${.OBJDIR}
.MAKEOVERRIDES+= LIBOBJ
.include <bsd.subdir.mk>
.include <bsd.obj.mk>
cleandir distclean: .WAIT cleanlibdir
cleanlibdir:
-rm -rf lib

View file

@ -0,0 +1,154 @@
# $NetBSD: Makefile.bootxx,v 1.42 2011/06/20 06:52:38 mrg Exp $
S= ${.CURDIR}/../../../../..
AFLAGS.bootxx.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.label.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.pbr.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
PIE_CFLAGS=
PIE_LDFLAGS=
PIE_AFLAGS=
NOMAN=
PROG?= bootxx_${FS}
BINDIR= /usr/mdec
BINMODE= 0444
PRIMARY_LOAD_ADDRESS=0x1000
SECONDARY_LOAD_ADDRESS=0x10000
# We ought (need?) to fit into track 0 of a 1.2M floppy.
# This restricts us to 15 sectors (including pbr and label)
BOOTXX_SECTORS?=15
BOOTXX_MAXSIZE?= $$(( ${BOOTXX_SECTORS} * 512 ))
SRCS= pbr.S label.S bootxx.S boot1.c
.include <bsd.own.mk>
STRIPFLAG= # nothing
LIBCRT0= # nothing
LIBCRTBEGIN= # nothing
LIBCRTEND= # nothing
LIBC= # nothing
BINDIR=/usr/mdec
BINMODE=444
.PATH: ${.CURDIR}/.. ${.CURDIR}/../../lib
LDFLAGS+= -nostdlib -Wl,-N -Wl,-e,start
CPPFLAGS+= -DBOOTXX
# CPPFLAGS+= -D__daddr_t=int32_t
CPPFLAGS+= -I ${.CURDIR}/../../lib -I ${.OBJDIR}
CPPFLAGS+= -DBOOTXX_SECTORS=${BOOTXX_SECTORS}
CPPFLAGS+= -DPRIMARY_LOAD_ADDRESS=${PRIMARY_LOAD_ADDRESS}
CPPFLAGS+= -DSECONDARY_LOAD_ADDRESS=${SECONDARY_LOAD_ADDRESS}
CPPFLAGS+= -DXXfs_open=${FS}_open
CPPFLAGS+= -DXXfs_close=${FS}_close
CPPFLAGS+= -DXXfs_read=${FS}_read
CPPFLAGS+= -DXXfs_stat=${FS}_stat
CPPFLAGS+= -DFS=${FS}
# CPPFLAGS+= -DBOOT_MSG_COM0
# Make sure we override any optimization options specified by the user
.include "${.PARSEDIR}/../Makefile.inc"
COPTS= ${OPT_SIZE.${ACTIVE_CC}}
DBG=
CPPFLAGS+= -DNO_LBA_CHECK
.if defined(HAVE_GCC)
.if ${MACHINE_ARCH} == "x86_64"
LDFLAGS+= -Wl,-m,elf_i386
AFLAGS+= -m32
CPUFLAGS= -m32
LIBKERN_ARCH=i386
KERNMISCMAKEFLAGS="LIBKERN_ARCH=i386"
.else
CPPFLAGS+= -DEPIA_HACK
CPUFLAGS= -march=i386 -mtune=i386
.endif
.endif
CFLAGS+= -Wall -Wmissing-prototypes -Wstrict-prototypes
CPPFLAGS+= -nostdinc -D_STANDALONE
CPPFLAGS+= -I$S
CPPFLAGS+= -DLIBSA_SINGLE_FILESYSTEM=xxfs \
-DLIBSA_NO_TWIDDLE \
-DLIBSA_NO_FD_CHECKING \
-DLIBSA_NO_RAW_ACCESS \
-DLIBSA_NO_FS_WRITE \
-DLIBSA_NO_FS_SEEK \
-DLIBSA_SINGLE_DEVICE=blkdev \
-DLIBKERN_OPTIMISE_SPACE \
-D"blkdevioctl(x,y,z)=EINVAL" \
-D"blkdevclose(f)=0" \
-D"devopen(f,n,fl)=(*(fl)=(void *)n,0)" \
-DLIBSA_NO_DISKLABEL_MSGS
# -DLIBSA_FS_SINGLECOMPONENT
# CPPFLAGS+= -DBOOTXX_RAID1_SUPPORT
I386_STAND_DIR?= $S/arch/i386/stand
CLEANFILES+= machine x86
.if !make(obj) && !make(clean) && !make(cleandir)
.BEGIN:
-rm -f machine && ln -s $S/arch/i386/include machine
-rm -f x86 && ln -s $S/arch/x86/include x86
.ifdef LIBOBJ
-rm -f lib && ln -s ${LIBOBJ}/lib lib
mkdir -p ${LIBOBJ}/lib
.endif
.endif
### find out what to use for libi386
I386DIR= ${I386_STAND_DIR}/lib
.include "${I386DIR}/Makefile.inc"
LIBI386= ${I386LIB}
### find out what to use for libsa
SA_AS= library
SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes"
.include "${S}/lib/libsa/Makefile.inc"
LIBSA= ${SALIB}
### find out what to use for libkern
KERN_AS= library
.include "${S}/lib/libkern/Makefile.inc"
LIBKERN= ${KERNLIB}
cleandir distclean: .WAIT cleanlibdir
cleanlibdir:
-rm -rf lib
LIBLIST= ${LIBI386} ${LIBSA} ${LIBKERN} ${LIBI386} ${LIBSA}
CLEANFILES+= ${PROG}.sym ${PROG}.map
${PROG}: ${OBJS} ${LIBLIST}
${_MKTARGET_LINK}
${CC} -o ${PROG}.sym ${LDFLAGS} -Wl,-Ttext,${PRIMARY_LOAD_ADDRESS} \
-Wl,-Map,${PROG}.map -Wl,-cref ${OBJS} ${LIBLIST}
${OBJCOPY} -O binary ${PROG}.sym ${PROG}
@ sz=$$(${TOOL_STAT} -f '%z' ${PROG}); \
if [ "$$sz" -gt "${BOOTXX_MAXSIZE}" ]; then \
echo "### ${PROG} size $$sz is larger than ${BOOTXX_MAXSIZE}" >&2; \
rm ${PROG}; \
! :; \
else \
: pad to sector boundary; \
pad=$$(( 512 - ( $$sz & 511 ) )); \
[ $$pad = 512 ] || \
dd if=/dev/zero bs=1 count=$$pad >>${PROG} 2>/dev/null; \
echo "${PROG} size $$sz, $$((${BOOTXX_MAXSIZE} - $$sz)) free"; \
fi
.include <bsd.prog.mk>

View file

@ -0,0 +1,158 @@
/* $NetBSD: boot1.c,v 1.20 2011/01/06 01:08:48 jakllsch Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: boot1.c,v 1.20 2011/01/06 01:08:48 jakllsch Exp $");
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <biosdisk_ll.h>
#include <sys/param.h>
#include <sys/bootblock.h>
#include <sys/disklabel.h>
#include <dev/raidframe/raidframevar.h> /* For RF_PROTECTED_SECTORS */
#define XSTR(x) #x
#define STR(x) XSTR(x)
static daddr_t bios_sector;
static struct biosdisk_ll d;
const char *boot1(uint32_t, uint64_t *);
extern void putstr(const char *);
extern struct disklabel ptn_disklabel;
static int
ob(void)
{
return open("boot", 0);
}
const char *
boot1(uint32_t biosdev, uint64_t *sector)
{
struct stat sb;
int fd;
bios_sector = *sector;
d.dev = biosdev;
putstr("\r\nNetBSD/x86 " STR(FS) " Primary Bootstrap\r\n");
if (set_geometry(&d, NULL))
return "set_geometry\r\n";
/*
* We default to the filesystem at the start of the
* MBR partition
*/
fd = ob();
if (fd != -1)
goto done;
/*
* Maybe the filesystem is enclosed in a raid set.
* add in size of raidframe header and try again.
* (Maybe this should only be done if the filesystem
* magic number is absent.)
*/
bios_sector += RF_PROTECTED_SECTORS;
fd = ob();
if (fd != -1)
goto done;
#ifdef BOOT_FROM_MINIXFS3
bios_sector -= RF_PROTECTED_SECTORS;
bios_sector += 32; /* XXX put somewhere as constant */
*sector = bios_sector;
fd = ob();
if (fd != -1)
goto done;
#endif
/*
* Nothing at the start of the MBR partition, fallback on
* partition 'a' from the disklabel in this MBR partition.
*/
if (ptn_disklabel.d_magic != DISKMAGIC ||
ptn_disklabel.d_magic2 != DISKMAGIC ||
ptn_disklabel.d_partitions[0].p_fstype == FS_UNUSED)
goto done;
bios_sector = ptn_disklabel.d_partitions[0].p_offset;
*sector = bios_sector;
if (ptn_disklabel.d_partitions[0].p_fstype == FS_RAID)
bios_sector += RF_PROTECTED_SECTORS;
fd = ob();
done:
/* if we fail here, so will fstat, so keep going */
if (fd == -1 || fstat(fd, &sb) == -1)
return "Can't open /boot\r\n";
biosdev = (uint32_t)sb.st_size;
#if 0
if (biosdev > SECONDARY_MAX_LOAD)
return "/boot too large\r\n";
#endif
if (read(fd, (void *)SECONDARY_LOAD_ADDRESS, biosdev) != biosdev)
return "/boot load failed\r\n";
if (*(uint32_t *)(SECONDARY_LOAD_ADDRESS + 4) != X86_BOOT_MAGIC_2)
return "Invalid /boot file format\r\n";
/* We need to jump to the secondary bootstrap in realmode */
return 0;
}
int
blkdevstrategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize)
{
if (flag != F_READ)
return EROFS;
if (size & (BIOSDISK_DEFAULT_SECSIZE - 1))
return EINVAL;
if (rsize)
*rsize = size;
if (size != 0 && readsects(&d, bios_sector + dblk,
size / BIOSDISK_DEFAULT_SECSIZE,
buf, 1) != 0)
return EIO;
return 0;
}

View file

@ -0,0 +1,136 @@
/* $NetBSD: bootxx.S,v 1.10 2011/01/06 01:08:48 jakllsch Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
#include <sys/bootblock.h>
/*
* Code linked to 0xa00 and copied to sectors 2+ of the netbsd boot
* partition by MI /usr/sbin/installboot.
* Read into memory by code in pbr.S
*
* On entry:
* %dl BIOS drive number
* %edi:%esi Sector number of NetBSD partition
* %cs, %ds, %es, %ss All zero
* %sp near 0xfffc
*/
.text
.code16
ENTRY(bootxx)
jmp 1f
.balign 4
ENTRY(bootxx_magic)
.long X86_BOOT_MAGIC_1 /* checked by installboot & pbr code */
boot_params: /* space for patchable variables */
.long 1f - boot_params /* length of this data area */
#include <boot_params.S>
. = bootxx + 0x80 /* Space for patching unknown params */
1: call gdt_fixup
calll real_to_prot
.code32
push %edi
movl $_end, %ecx /* zero bss */
movl $__bss_start, %edi
subl %edi, %ecx
shr $2, %ecx /* _end and __bss_start are aligned */
xor %eax, %eax
rep
stosl
pop %edi
movzbl %dl, %edx
push %edi /* save args for secondary bootstrap */
push %esi
movl %esp, %esi /* address of sector number */
push %edx
push %esi /* args for boot1 */
push %edx
call _C_LABEL(boot1) /* C code to load /boot */
add $8, %esp
call prot_to_real
.code16
test %ax, %ax
jnz boot_fail
pop %edx /* bios disk number */
pop %ebx /* expected partition start sector */
pop %ecx
movl $boot_params, %esi
orb $X86_BP_FLAGS_LBA64VALID, 4(%esi)
lcall $SECONDARY_LOAD_ADDRESS/16, $0
boot_fail:
push %ax /* error string from boot1 */
movw errno, %ax
aam /* largest errno is < 100 */
addw $('0' << 8) | '0', %ax /* to ascii */
rorw $8, %ax
cmpb $'0', %al /* supress leading zero */
jne 10f
movb $' ', %al
10: movw %ax, 12f
movw $11f, %si
call message /* output boot failed message */
pop %si
call message /* and text from boot1 */
jmp loopstop
11: .ascii "Boot failed (errno "
12: .asciz "xx): "
ENTRY(_rtt)
.code32
call prot_to_real
.code16
loopstop:
movb 0x86, %ah /* delay for about a second */
movw $16, %cx
int $0x15
int $0x18 /* might be a boot fail entry */
1: sti /* if not loopstop */
hlt
jmp 1b
/*
* Vector the fs calls through here so we can support multiple
* file system types with one copy of the library code and
* multiple copies of this file.
*/
.global xxfs_open, xxfs_close, xxfs_read, xxfs_stat
.code32
xxfs_open: jmp XXfs_open
xxfs_close: jmp XXfs_close
xxfs_read: jmp XXfs_read
xxfs_stat: jmp XXfs_stat

View file

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2010/09/11 13:06:37 tsutsui Exp $
FS=ext2fs
.include <../Makefile.bootxx>

View file

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:10 dsl Exp $
FS=ffsv1
.include <../Makefile.bootxx>

View file

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:10 dsl Exp $
FS=ffsv2
.include <../Makefile.bootxx>

View file

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:10 dsl Exp $
FS=lfsv1
.include <../Makefile.bootxx>

View file

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:11 dsl Exp $
FS=lfsv2
.include <../Makefile.bootxx>

View file

@ -0,0 +1,7 @@
# $NetBSD$
PROG=bootxx_minixfs3
FS=minixfs3
CPPFLAGS=-DBOOT_FROM_MINIXFS3 -DTERSE_ERROR
.include <../Makefile.bootxx>

View file

@ -0,0 +1,7 @@
# $NetBSD: Makefile,v 1.3 2005/12/11 12:17:48 christos Exp $
PROG= bootxx_msdos
FS= dosfs
CPPFLAGS=-DBOOT_FROM_FAT -DTERSE_ERROR
.include <../Makefile.bootxx>

View file

@ -0,0 +1,7 @@
# $NetBSD: Makefile,v 1.3 2009/11/18 21:02:16 dsl Exp $
FS=ustarfs
BOOTXX_SECTORS=16
.include <../Makefile.bootxx>

View file

@ -0,0 +1,19 @@
/* $NetBSD: label.S,v 1.3 2005/12/11 12:17:48 christos Exp $ */
#include <machine/asm.h>
/*
* This fills in the space taken by the NetBSD disklabel in the first
* NetBSD partition on the disk.
* However it is possible that we are booting from a subsequent
* NetBSD partition, so must not access the disklabel in this space.
*
* Recent kernels (but not the disklabel program) write the label to
* all NetBSD MBR partitions (including extended ones).
* So we make it available to boot1().
*/
.text
.global _C_LABEL(ptn_disklabel)
_C_LABEL(ptn_disklabel):
.fill 512

View file

@ -0,0 +1,447 @@
/* $NetBSD: pbr.S,v 1.20 2011/08/17 00:07:38 jakllsch Exp $ */
/*-
* Copyright (c) 2003,2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* i386 partition boot code
*
* This code resides in sector zero of the netbsd partition, or sector
* zero of an unpartitioned disk (eg a floppy).
* Sector 1 is assumed to contain the netbsd disklabel.
* Sectors 2 until the end of the track contain the next phase of bootstrap.
* Which know how to read the interactive 'boot' program from filestore.
* The job of this code is to read in the phase 1 bootstrap.
*
* Makefile supplies:
* PRIMARY_LOAD_ADDRESS: Address we load code to (0x1000).
* BOOTXX_SECTORS: Number of sectors we load (15).
* X86_BOOT_MAGIC_1: A random magic number.
*
* Although this code is executing at 0x7c00, it is linked to address 0x1000.
* All data references MUST be fixed up using R().
*/
#include <machine/asm.h>
#include <sys/bootblock.h>
#define OURADDR 0x7c00 /* our address */
#define BOOTADDR PRIMARY_LOAD_ADDRESS
#define R(a) (a - BOOTADDR + OURADDR)
#define lba_info R(_lba_info)
#define lba_sector R(_lba_sector)
#define errtxt R(_errtxt)
#define errcod R(_errcod)
#define newline R(_newline)
#define TABENTRYSIZE (MBR_BS_PARTNAMESIZE + 1)
#define NAMETABSIZE (4 * TABENTRYSIZE)
#ifdef BOOT_FROM_FAT
#define MBR_AFTERBPB 90 /* BPB size in FAT32 partition BR */
#else
#define MBR_AFTERBPB 62 /* BPB size in floppy master BR */
#endif
#ifdef TERSE_ERROR
/*
* Error codes. Done this way to save space.
*/
#define ERR_READ '2' /* Read error */
#define ERR_NO_BOOTXX 'B' /* No bootxx_xfs in 3rd sector */
#define ERR_PTN 'P' /* partition not defined */
#define ERR_NO_LBA 'L' /* sector above chs limit */
#define set_err(err) movb $err, %al
#else
#define set_err(err) mov $R(err), %ax
#endif
/*
* This code is loaded to addresss 0:7c00 by either the system BIOS
* (for a floppy) or the mbr boot code. Since the boot program will
* be loaded to address 1000:0, we don't need to relocate ourselves
* and can load the subsequent blocks (that load boot) to an address
* of our choosing. 0:1000 is a not unreasonable choice.
*
* On entry the BIOS drive number is in %dl and %esi may contain the
* sector we were loaded from (if we were loaded by NetBSD mbr code).
* In any case we have to re-read sector zero of the disk and hunt
* through the BIOS partition table for the NetBSD partition.
*
* Or, we may have been loaded by a GPT hybrid MBR, handoff state is
* specified in T13 EDD-4 annex A.
*/
.text
.code16
ENTRY(start)
/*
* The PC BIOS architecture defines a Boot Parameter Block (BPB) here.
* The actual format varies between different MS-DOS versions, but
* apparently some system BIOS insist on patching this area
* (especially on LS120 drives - which I thought had an MBR...).
* The initial jmp and nop are part of the standard and may be
* tested for by the system BIOS.
*/
jmp start0
nop
.ascii "NetBSD60" /* oemname (8 bytes) */
. = start + MBR_BPB_OFFSET /* move to start of BPB */
/* (ensures oemname doesn't overflow) */
. = start + MBR_AFTERBPB /* skip BPB */
start0:
xor %cx, %cx /* don't trust values of ds, es or ss */
mov %cx, %ss
mov %cx, %sp
mov %cx, %es
#ifndef BOOT_FROM_FAT
cmpl $0x54504721, %eax /* did a GPT hybrid MBR start us? */
je boot_gpt
#endif
mov %cx, %ds
xor %ax, %ax
/* A 'reset disk system' request is traditional here... */
push %dx /* some BIOS zap %dl here :-( */
int $0x13 /* ah == 0 from code above */
pop %dx
/* Read from start of disk */
incw %cx /* track zero sector 1 */
movb %ch, %dh /* dh = head = 0 */
call chs_read
/* See if this is our code, if so we have already loaded the next stage */
xorl %ebp, %ebp /* pass sector 0 to next stage */
movl (%bx), %eax /* MBR code shouldn't even have ... */
cmpl R(start), %eax /* ... a jmp at the start. */
je pbr_read_ok1
/* Now scan the MBR partition table for a netbsd partition */
xorl %ebx, %ebx /* for base extended ptn chain */
scan_ptn_tbl:
xorl %ecx, %ecx /* for next extended ptn */
movw $BOOTADDR + MBR_PART_OFFSET, %di
1: movb 4(%di), %al /* mbrp_type */
movl 8(%di), %ebp /* mbrp_start == LBA sector */
addl lba_sector, %ebp /* add base of extended partition */
#ifdef BOOT_FROM_FAT
cmpb $MBR_PTYPE_FAT12, %al
je 5f
cmpb $MBR_PTYPE_FAT16S, %al
je 5f
cmpb $MBR_PTYPE_FAT16B, %al
je 5f
cmpb $MBR_PTYPE_FAT32, %al
je 5f
cmpb $MBR_PTYPE_FAT32L, %al
je 5f
cmpb $MBR_PTYPE_FAT16L, %al
je 5f
#elif BOOT_FROM_MINIXFS3
cmpb $MBR_PTYPE_MINIX_14B, %al
je 5f
#else
cmpb $MBR_PTYPE_NETBSD, %al
#endif
jne 10f
5: testl %esi, %esi /* looking for a specific sector? */
je boot
cmpl %ebp, %esi /* ptn we wanted? */
je boot
/* check for extended partition */
10: cmpb $MBR_PTYPE_EXT, %al
je 15f
cmpb $MBR_PTYPE_EXT_LBA, %al
je 15f
cmpb $MBR_PTYPE_EXT_LNX, %al
jne 20f
15: movl 8(%di), %ecx /* sector of next ext. ptn */
20: add $0x10, %di
cmp $BOOTADDR + MBR_MAGIC_OFFSET, %di
jne 1b
/* not in base partitions, check extended ones */
jecxz no_netbsd_ptn
testl %ebx, %ebx
jne 30f
xchgl %ebx, %ecx /* save base of ext ptn chain */
30: addl %ebx, %ecx /* address this ptn */
movl %ecx, lba_sector /* sector to read */
call read_lba
jmp scan_ptn_tbl
no_netbsd_ptn:
/* Specific sector not found: try again looking for first NetBSD ptn */
testl %esi, %esi
set_err(ERR_PTN)
jz error
xorl %esi, %esi
movl %esi, lba_sector
jmp start
/*
* Sector below CHS limit
* Do a cylinder-head-sector read instead
* I believe the BIOS should do reads that cross track boundaries.
* (but the read should start at the beginning of a track...)
*/
read_chs:
movb 1(%di), %dh /* head */
movw 2(%di), %cx /* ch=cyl, cl=sect */
call chs_read
pbr_read_ok1:
jmp pbr_read_ok
/*
* Active partition pointed to by di.
*
* We can either do a CHS (Cylinder Head Sector) or an LBA (Logical
* Block Address) read. Always doing the LBA one
* would be nice - unfortunately not all systems support it.
* Also some may contain a separate (eg SCSI) BIOS that doesn't
* support it even when the main BIOS does.
*
* The safest thing seems to be to find out whether the sector we
* want is inside the CHS sector count. If it is we use CHS, if
* outside we use LBA.
*
* Actually we check that the CHS values reference the LBA sector,
* if not we assume that the LBA sector is above the limit, or that
* the geometry used (by fdisk) isn't correct.
*/
boot:
movl %ebp, lba_sector /* to control block */
testl %ebx, %ebx /* was it an extended ptn? */
jnz boot_lba /* yes - boot with LBA reads */
/* get CHS values from BIOS */
push %dx /* save drive number */
movb $8, %ah
int $0x13 /* chs info */
/*
* Validate geometry, if the CHS sector number doesn't match the LBA one
* we'll do an LBA read.
* calc: (cylinder * number_of_heads + head) * number_of_sectors + sector
* and compare against LBA sector number.
* Take a slight 'flier' and assume we can just check 16bits (very likely
* to be true because the number of sectors per track is 63).
*/
movw 2(%di), %ax /* cylinder + sector */
push %ax /* save for sector */
shr $6, %al
xchgb %al, %ah /* 10 bit cylinder number */
shr $8, %dx /* last head */
inc %dx /* number of heads */
mul %dx
mov 1(%di), %dl /* head we want */
add %dx, %ax
and $0x3f, %cx /* number of sectors */
mul %cx
pop %dx /* recover sector we want */
and $0x3f, %dx
add %dx, %ax
dec %ax
pop %dx /* recover drive nmber */
cmp %bp, %ax
je read_chs
check_lba:
#ifdef NO_LBA_CHECK
jmp boot_lba
#else
/*
* Determine whether we have int13-extensions, by calling
* int 13, function 41. Check for the magic number returned,
* and the disk packet capability.
*
* This is actually relatively pointless:
* 1) we only use LBA reads if CHS ones would fail
* 2) the MBR code managed to read the same sectors
* 3) the BIOS will (ok should) reject the LBA read as a bad BIOS call
*/
movw $0x55aa, %bx
movb $0x41, %ah
int $0x13
jc 1f /* no int13 extensions */
cmpw $0xaa55, %bx
jnz 1f
testb $1, %cl
jnz boot_lba
1: set_err(ERR_NO_LBA)
#endif /* NO_LBA_CHECK */
/*
* Something went wrong,
* Output error code,
*/
error:
#ifdef TERSE_ERROR
movb %al, errcod
movw $errtxt, %si
call message
#else
push %ax
movw $errtxt, %si
call message
pop %si
call message
movw $newline, %si
call message
#endif
1: sti
hlt
jmp 1b
boot_lba:
call read_lba
/*
* Check magic number for valid stage 2 bootcode
* then jump into it.
*/
pbr_read_ok:
cmpl $X86_BOOT_MAGIC_1, bootxx_magic
set_err(ERR_NO_BOOTXX)
jnz error
movl %ebp, %esi /* %esi ptn base, %dl disk id */
movl lba_sector + 4, %edi /* %edi ptn base high */
jmp $0, $bootxx /* our %cs may not be zero */
/* Read disk using int13-extension parameter block */
read_lba:
pusha
movw $lba_info, %si /* ds:si is ctl block */
movb $0x42, %ah
do_read:
int $0x13
popa
set_err(ERR_READ)
jc error
ret
/* Read using CHS */
chs_read:
movw $BOOTADDR, %bx /* es:bx is buffer */
pusha
movw $0x200 + BOOTXX_SECTORS, %ax /* command 2, xx sectors */
jmp do_read
#ifndef BOOT_FROM_FAT
boot_gpt:
movl (20+32+0)(%si), %ebp
movl (20+32+4)(%si), %edi
movw %cx, %ds
movl %ebp, lba_sector + 0
movl %edi, lba_sector + 4
movl %ebp, %esi
jmp boot_lba
#endif
_errtxt: .ascii "Error " /* runs into newline... */
_errcod: .byte 0 /* ... if errcod set */
_newline:
.asciz "\r\n"
#ifndef TERSE_ERROR
ERR_READ: .asciz "read"
ERR_NO_BOOTXX: .asciz "no magic"
ERR_PTN: .asciz "no slice"
#ifndef NO_LBA_CHECK
ERR_NO_LBA: .asciz "need LBA"
#endif
#endif
/*
* I hate #including source files, but pbr_magic below has to be at
* the correct absolute address.
* Clearly this could be done with a linker script.
*/
#include <message.S>
#if 0
#include <dump_eax.S>
#endif
/* Control block for int-13 LBA read. */
_lba_info:
.word 0x10 /* control block length */
.word BOOTXX_SECTORS /* sector count */
.word BOOTADDR /* offset in segment */
.word 0 /* segment */
_lba_sector:
.quad 0 /* sector # goes here... */
/* Drive Serial Number */
. = _C_LABEL(start) + MBR_DSN_OFFSET
.long 0
/* mbr_bootsel_magic (not used here) */
. = _C_LABEL(start) + MBR_BS_MAGIC_OFFSET
.word 0
/*
* Provide empty MBR partition table.
* If this is installed as an MBR, the user can use fdisk(8) to create
* the correct partition table ...
*/
. = _C_LABEL(start) + MBR_PART_OFFSET
_pbr_part0:
.byte 0, 0, 0, 0, 0, 0, 0, 0
.long 0, 0
_pbr_part1:
.byte 0, 0, 0, 0, 0, 0, 0, 0
.long 0, 0
_pbr_part2:
.byte 0, 0, 0, 0, 0, 0, 0, 0
.long 0, 0
_pbr_part3:
.byte 0, 0, 0, 0, 0, 0, 0, 0
.long 0, 0
/*
* The magic comes last
*/
. = _C_LABEL(start) + MBR_MAGIC_OFFSET
pbr_magic:
.word MBR_MAGIC

View file

@ -0,0 +1,80 @@
# $NetBSD: Makefile,v 1.35 2011/06/22 02:49:44 mrg Exp $
S?= ${.CURDIR}/../../../..
LIB= i386
NOPIC=# defined
NOPROFILE=# defined
I386_INCLUDE_DISK?= yes
I386_INCLUDE_DOS?= no
I386_INCLUDE_BUS?= no
I386_INCLUDE_PS2?= yes
AFLAGS.biosdelay.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosgetrtc.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosgetsystime.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosmca.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosmemps2.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosmem.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosmemx.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosreboot.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosvbe.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.biosvideomode.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.bios_disk.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.bios_pci.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.comio.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.conio.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.dos_file.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.dump_eax.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.message.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.message32.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.pvcopy.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.putstr.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.putstr32.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
AFLAGS.realprot.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
CPPFLAGS= -I$S/lib/libsa ${I386CPPFLAGS} ${I386MISCCPPFLAGS}
#CPPFLAGS+= -DDISK_DEBUG
#CPPFLAGS+= -DNO_DISKLABEL
#CPPFLAGS+= -DNO_GPT
#CPPFLAGS+= -DSAVE_MEMORY
SRCS= pcio.c conio.S comio.S comio_direct.c biosvideomode.S
SRCS+= getsecs.c biosgetrtc.S biosdelay.S biosreboot.S gatea20.c
SRCS+= biosmem.S getextmemx.c biosmemx.S printmemlist.c
SRCS+= pread.c menuutils.c parseutils.c
SRCS+= bootinfo.c bootinfo_biosgeom.c bootinfo_memmap.c
SRCS+= startprog.S multiboot.S
SRCS+= biosgetsystime.S cpufunc.S bootmenu.c
SRCS+= realprot.S message.S message32.S dump_eax.S pvcopy.S putstr.S putstr32.S
SRCS+= rasops.c vbe.c biosvbe.S
.if (${I386_INCLUDE_DISK} == "yes")
SRCS+= biosdisk.c biosdisk_ll.c bios_disk.S
.endif
.if (${I386_INCLUDE_DOS} == "yes")
SRCS+= dosfile.c dos_file.S
.endif
.if (${I386_INCLUDE_DISK} == "yes") || (${I386_INCLUDE_DOS} == "yes")
SRCS+= diskbuf.c
.endif
.if (${I386_INCLUDE_BUS} == "yes")
SRCS+= biospci.c bios_pci.S isapnp.c isadma.c
.endif
.if (${I386_INCLUDE_PS2} == "yes")
SRCS+= biosmca.S biosmemps2.S
.endif
.include <bsd.own.mk>
.undef DESTDIR
.include <bsd.lib.mk>
lib${LIB}.o:: ${OBJS}
@echo building standard ${LIB} library
@rm -f lib${LIB}.o
@${LD} -r -o lib${LIB}.o `lorder ${OBJS} | tsort`
# XXX
.if ${HAVE_GCC} == 45
COPTS.biosdisk.c+= -fno-strict-aliasing
.endif

View file

@ -0,0 +1,55 @@
# $NetBSD: Makefile.inc,v 1.14 2011/05/26 12:56:30 joerg Exp $
#
# Configuration variables (default values are below):
#
# S must be set to the top of the 'sys' tree.
# I386DST may be set to the location of the directory where library
# objects are to be built. Defaults to ${.OBJDIR}/lib/i386.
# I386MISCCPPFLAGS
# Miscellaneous cpp flags to be passed to the library's Makefile
# when building.
# I386MISCMAKEFLAGS
# Miscellaneous flags to be passed to the library's Makefile when
# building. See library's Makefile for more details about
# supported flags and their default values.
# Default values:
I386DST?= ${.OBJDIR}/lib/i386
#I386DIR= $S/arch/i386/stand/lib
I386LIB= ${I386DST}/libi386.a
CWARNFLAGS.clang+= -Wno-tautological-compare
I386MAKE= \
cd ${I386DIR} && MAKEOBJDIRPREFIX= && unset MAKEOBJDIRPREFIX && \
MAKEOBJDIR=${I386DST} ${MAKE} \
CC=${CC:Q} CFLAGS=${CFLAGS:Q} \
AS=${AS:Q} AFLAGS=${AFLAGS:Q} \
LD=${LD:Q} STRIP=${STRIP:Q} \
MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH:Q} \
I386CPPFLAGS=${CPPFLAGS:S@^-I.@-I../../.@g:Q} \
I386MISCCPPFLAGS=${I386MISCCPPFLAGS:Q} \
${I386MISCMAKEFLAGS}
${I386LIB}: .NOTMAIN __always_make_i386lib
@echo making sure the i386 library is up to date...
@${I386MAKE} libi386.a
clean: .NOTMAIN cleani386lib
cleani386lib: .NOTMAIN
@echo cleaning the i386 library objects
@if [ -d "${I386DST}" ]; then ${I386MAKE} clean; fi
cleandir distclean: .NOTMAIN cleandiri386lib
cleandiri386lib: .NOTMAIN
@echo cleandiring the i386 library objects
@if [ -d "${I386DST}" ]; then ${I386MAKE} cleandir; fi
dependall depend: .NOTMAIN dependi386lib
dependi386lib: .NOTMAIN __always_make_i386lib
@echo depending the i386 library objects
@${I386MAKE} depend
__always_make_i386lib: .NOTMAIN
@mkdir -p ${I386DST}

View file

@ -0,0 +1,297 @@
/* $NetBSD: bios_disk.S,v 1.21 2011/06/16 13:27:59 joerg Exp $ */
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* 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.
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* extracted from netbsd:sys/arch/i386/boot/bios.S */
#include <machine/asm.h>
/*
* BIOS call "INT 0x13 Function 0x0" to reset the disk subsystem
* Call with %ah = 0x0
* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
* Return:
* %al = 0x0 on success; err code on failure
*/
ENTRY(biosdisk_reset)
pusha
movb %al, %dl # device
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x0, %ah # subfunction
int $0x13
setc %bl
movb %ah, %bh # save error code
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movzwl %bx, %eax # return value in %eax
movl %eax, 28(%esp)
popa
ret
/*
* BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
* Call with %ah = 0x2
* %al = number of sectors
* %ch = cylinder
* %cl = sector
* %dh = head
* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
* %es:%bx = segment:offset of buffer
* Return:
* %al = 0x0 on success; err code on failure
*
* biosdisk_read(dev, cyl, head, sect, count, buff_addr);
*
* Note: On failure, you must reset the disk with biosdisk_reset() before
* sending another command.
*/
ENTRY(biosdisk_read)
pusha
movb 44(%esp), %dh
movw 40(%esp), %cx
xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
rorb $2, %cl
movb 48(%esp), %al
orb %al, %cl
incb %cl # sector; sec starts from 1, not 0
movb 36(%esp), %dl # device
movl 56(%esp), %ebx # buffer address (may be >64k)
movb 52(%esp), %al # number of sectors
call _C_LABEL(prot_to_real) # enter real mode
.code16
push %bx
shrl $4, %ebx # max segment
mov %ds, %si
add %si, %bx
mov %bx, %es # %es:%bx now valid buffer address
pop %bx
and $0xf, %bx # and min offset - to avoid overrun
movb $0x2, %ah # subfunction
int $0x13
setc %al # error code is in %ah
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl %eax, 28(%esp)
popa
ret
/*
* biosdisk_getinfo(int dev): return a word that represents the
* max number of sectors, heads and cylinders for this device
*/
ENTRY(biosdisk_getinfo)
push %es
pusha
movb %al, %dl # diskinfo(drive #)
call _C_LABEL(prot_to_real) # enter real mode
.code16
push %dx # save drive #
movb $0x08, %ah # ask for disk info
int $0x13
pop %bx # restore drive #
jnc ok
testb $0x80, %bl # is it a hard disk?
jnz ok
/*
* Urk. Call failed. It is not supported for floppies by old BIOS's.
* Guess it's a 15-sector floppy. Initialize all the registers for
* documentation, although we only need head and sector counts.
*/
xorw %ax, %ax # set status to success
# movb %ah, %bh # %bh = 0
# movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
movb $79, %ch # max track
movb $15, %cl # max sector
movb $1, %dh # max head
# movb $1, %dl # # floppy drives installed
# es:di = parameter table
# carry = 0
ok:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
/* form a longword representing all this gunk */
shrl $8, %eax # clear unnecessary bits
shll $24, %eax
shll $16, %ecx # do the same for %ecx
shrl $8, %ecx
movb %dh, %cl # max head
orl %ecx, %eax # return value in %eax
movl %eax, 28(%esp)
popa
pop %es
ret
/*
* int biosdisk_int13ext(int dev):
* check for availibility of int13 extensions.
*/
ENTRY(biosdisk_int13ext)
pusha
movb %al, %dl # drive #
movw $0x55aa, %bx
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x41, %ah # ask for disk info
int $0x13
setnc %dl
calll _C_LABEL(real_to_prot) # switch back
.code32
movzbl %dl, %eax # return value in %eax
cmpw $0xaa55, %bx
sete %dl
andb %dl, %al
andb %cl, %al
movl %eax, 28(%esp)
popa
ret
/*
* BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
* Call with %ah = 0x42
* %ds:%si = parameter block (data buffer address
* must be a real mode physical address).
* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
* Return:
* %al = 0x0 on success; err code on failure
*/
ENTRY(biosdisk_extread)
pusha
movl %edx, %esi # parameter block
movb %al, %dl # device
call _C_LABEL(prot_to_real) # enter real mode
.code16
push %ds
movl %esi, %eax
shrl $4, %eax
movw %ds, %bx
addw %bx, %ax
movw %ax, %ds
andw $0xf, %si
movb $0x42, %ah # subfunction
int $0x13
setc %bl
movb %ah, %bh # save error code
pop %ds
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movzwl %bx, %eax # return value in %eax
movl %eax, 28(%esp)
popa
ret
ENTRY(biosdisk_getextinfo)
pusha
movl %edx, %esi # parameter block
movb %al, %dl # device
call _C_LABEL(prot_to_real) # enter real mode
.code16
push %ds
movl %esi, %eax
shrl $4, %eax
andw $0xf, %si
movw %ds, %bx
addw %bx, %ax
movw %ax, %ds
movb $0x48, %ah # subfunction
int $0x13
setc %bl
pop %ds
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movzbl %bl, %eax # return value in %eax
movl %eax, 28(%esp)
popa
ret

View file

@ -0,0 +1,214 @@
/* $NetBSD: bios_pci.S,v 1.6 2005/12/11 12:17:48 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* minimal calls to PCI BIOS */
#include <machine/asm.h>
#define addr32 .byte 0x67
#define data32 .byte 0x66
#define PCI_FUNCTION_ID 0xb1
#define PCI_BIOS_PRESENT 0x01
#define FIND_PCI_DEVICE 0x02
#define READ_CONFIG_DWORD 0x0a
#define WRITE_CONFIG_DWORD 0x0d
/* int pcibios_present(int *signature)
return: AX from BIOS call, -1 on error
var param: EDX from BIOS call, must be signature "PCI "
*/
ENTRY(pcibios_present)
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %ecx
pushl %edx
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $PCI_FUNCTION_ID, %ah
movb $PCI_BIOS_PRESENT, %al
int $0x1a
jnc ok1
movl $-1, %ebx
jmp err1
ok1:
xorl %ebx, %ebx
mov %ax, %bx
err1:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl 8(%ebp), %eax
movl %edx, (%eax)
movl %ebx, %eax # return value in %eax
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/* int pcibios_finddev(int vendor, int device, int index, int *busdevfcn)
return: AH from BIOS call, -1 on error
var param: BX from BIOS call, contains bus/device/function
*/
ENTRY(pcibios_finddev)
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
movl 16(%ebp), %esi
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $PCI_FUNCTION_ID, %ah
movb $FIND_PCI_DEVICE, %al
int $0x1a
jnc ok2
movl $-1, %edx
jmp err2
ok2:
movl $0,%edx
movb %ah, %dl
err2:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl 20(%ebp), %eax
mov %bx, (%eax)
movl %edx, %eax # return value in %eax
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/* int pcibios_cfgread(int busdevfcn, int offset, int *value)
return: AH from BIOS call, -1 on error
var param: ECX from BIOS call, contains value read
*/
ENTRY(pcibios_cfgread)
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
movl 8(%ebp), %ebx
movl 12(%ebp), %edi
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $PCI_FUNCTION_ID, %ah
movb $READ_CONFIG_DWORD, %al
int $0x1a
jnc ok3
movl $-1, %edx
jmp err3
ok3:
movl $0,%edx
movb %ah, %dl
err3:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl 16(%ebp), %eax
movl %ecx, (%eax)
movl %edx, %eax # return value in %eax
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/* int pcibios_cfgwrite(int busdevfcn, int offset, int value)
return: AH from BIOS call, -1 on error
var param: ECX from BIOS call, contains value read
*/
ENTRY(pcibios_cfgwrite)
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
movl 8(%ebp), %ebx
movl 12(%ebp), %edi
movl 16(%ebp), %ecx
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $PCI_FUNCTION_ID, %ah
movb $WRITE_CONFIG_DWORD, %al
int $0x1a
jnc ok4
movl $-1, %edx
jmp err4
ok4:
movl $0,%edx
movb %ah, %dl
err4:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl %edx, %eax # return value in %eax
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret

View file

@ -0,0 +1,78 @@
/* $NetBSD: biosdelay.S,v 1.4 2005/12/11 12:17:48 christos Exp $ */
/*
* Copyright (c) 1996, 1997
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
.text
/*
* BIOS call "INT 15H Function 86H" to sleep for a set number of microseconds
* Call with %ah = 0x86
* %cx = time interval (high)
* %dx = time interval (low)
* Return:
* If error
* CF = set
* else
* CF = clear
*/
ENTRY(delay)
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
movw 20(%esp), %dx
movw 22(%esp), %cx
call _C_LABEL(prot_to_real)
.code16
movb $0x86, %ah
int $0x15
setnc %ah
movb %ah, %bl # real_to_prot uses %eax
calll _C_LABEL(real_to_prot)
.code32
xorl %eax, %eax
movb %bl, %al
popl %edi
popl %esi
popl %ebx
popl %ebp
ret

View file

@ -0,0 +1,808 @@
/* $NetBSD: biosdisk.c,v 1.39 2011/09/21 08:57:12 gsutre Exp $ */
/*
* Copyright (c) 1996, 1998
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* raw BIOS disk device for libsa.
* needs lowlevel parts from bios_disk.S and biosdisk_ll.c
* partly from netbsd:sys/arch/i386/boot/disk.c
* no bad144 handling!
*
* A lot of this must match sys/kern/subr_disk_mbr.c
*/
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* 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.
*/
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
#define FSTYPENAMES
#endif
#include <lib/libkern/libkern.h>
#include <lib/libsa/stand.h>
#include <sys/types.h>
#include <sys/md5.h>
#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/disklabel_gpt.h>
#include <sys/uuid.h>
#include <fs/cd9660/iso.h>
#include <lib/libsa/saerrno.h>
#include <machine/cpu.h>
#include "libi386.h"
#include "biosdisk_ll.h"
#include "biosdisk.h"
#ifdef _STANDALONE
#include "bootinfo.h"
#endif
#define BUFSIZE 2048 /* must be large enough for a CD sector */
#define BIOSDISKNPART 26
struct biosdisk {
struct biosdisk_ll ll;
daddr_t boff;
char buf[BUFSIZE];
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
struct {
daddr_t offset;
daddr_t size;
int fstype;
} part[BIOSDISKNPART];
#endif
};
#ifndef NO_GPT
const struct uuid GET_nbsd_raid = GPT_ENT_TYPE_NETBSD_RAIDFRAME;
const struct uuid GET_nbsd_ffs = GPT_ENT_TYPE_NETBSD_FFS;
const struct uuid GET_nbsd_lfs = GPT_ENT_TYPE_NETBSD_LFS;
const struct uuid GET_nbsd_swap = GPT_ENT_TYPE_NETBSD_SWAP;
#endif /* NO_GPT */
#ifdef _STANDALONE
static struct btinfo_bootdisk bi_disk;
static struct btinfo_bootwedge bi_wedge;
#endif
#define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */
int
biosdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
void *buf, size_t *rsize)
{
struct biosdisk *d;
int blks, frag;
if (flag != F_READ)
return EROFS;
d = (struct biosdisk *) devdata;
if (d->ll.type == BIOSDISK_TYPE_CD)
dblk = dblk * DEV_BSIZE / ISO_DEFAULT_BLOCK_SIZE;
dblk += d->boff;
blks = size / d->ll.secsize;
if (blks && readsects(&d->ll, dblk, blks, buf, 0)) {
if (rsize)
*rsize = 0;
return EIO;
}
/* needed for CD */
frag = size % d->ll.secsize;
if (frag) {
if (readsects(&d->ll, dblk + blks, 1, d->buf, 0)) {
if (rsize)
*rsize = blks * d->ll.secsize;
return EIO;
}
memcpy(buf + blks * d->ll.secsize, d->buf, frag);
}
if (rsize)
*rsize = size;
return 0;
}
static struct biosdisk *
alloc_biosdisk(int biosdev)
{
struct biosdisk *d;
d = alloc(sizeof(*d));
if (d == NULL)
return NULL;
memset(d, 0, sizeof(*d));
d->ll.dev = biosdev;
if (set_geometry(&d->ll, NULL)) {
#ifdef DISK_DEBUG
printf("no geometry information\n");
#endif
dealloc(d, sizeof(*d));
return NULL;
}
return d;
}
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
static void
md5(void *hash, const void *data, size_t len)
{
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, data, len);
MD5Final(hash, &ctx);
return;
}
#endif
#ifndef NO_GPT
static bool
guid_is_nil(const struct uuid *u)
{
static const struct uuid nil = { .time_low = 0 };
return (memcmp(u, &nil, sizeof(*u)) == 0 ? true : false);
}
static bool
guid_is_equal(const struct uuid *a, const struct uuid *b)
{
return (memcmp(a, b, sizeof(*a)) == 0 ? true : false);
}
static int
check_gpt(struct biosdisk *d, daddr_t sector)
{
struct gpt_hdr gpth;
const struct gpt_ent *ep;
const struct uuid *u;
daddr_t entblk;
size_t size;
uint32_t crc;
int sectors;
int entries;
int entry;
int i, j;
/* read in gpt_hdr sector */
if (readsects(&d->ll, sector, 1, d->buf, 1)) {
#ifdef DISK_DEBUG
printf("Error reading GPT header at %"PRId64"\n", sector);
#endif
return EIO;
}
gpth = *(const struct gpt_hdr *)d->buf;
if (memcmp(GPT_HDR_SIG, gpth.hdr_sig, sizeof(gpth.hdr_sig)))
return -1;
crc = gpth.hdr_crc_self;
gpth.hdr_crc_self = 0;
gpth.hdr_crc_self = crc32(0, (const void *)&gpth, GPT_HDR_SIZE);
if (gpth.hdr_crc_self != crc) {
return -1;
}
if (gpth.hdr_lba_self != sector)
return -1;
#ifdef _STANDALONE
bi_wedge.matchblk = sector;
bi_wedge.matchnblks = 1;
md5(bi_wedge.matchhash, d->buf, d->ll.secsize);
#endif
sectors = sizeof(d->buf)/d->ll.secsize; /* sectors per buffer */
entries = sizeof(d->buf)/gpth.hdr_entsz; /* entries per buffer */
entblk = gpth.hdr_lba_table;
crc = crc32(0, NULL, 0);
j = 0;
ep = (const struct gpt_ent *)d->buf;
for (entry = 0; entry < gpth.hdr_entries; entry += entries) {
size = MIN(sizeof(d->buf),
(gpth.hdr_entries - entry) * gpth.hdr_entsz);
entries = size / gpth.hdr_entsz;
sectors = roundup(size, d->ll.secsize) / d->ll.secsize;
if (readsects(&d->ll, entblk, sectors, d->buf, 1))
return -1;
entblk += sectors;
crc = crc32(crc, (const void *)d->buf, size);
for (i = 0; j < BIOSDISKNPART && i < entries; i++, j++) {
u = (const struct uuid *)ep[i].ent_type;
if (!guid_is_nil(u)) {
d->part[j].offset = ep[i].ent_lba_start;
d->part[j].size = ep[i].ent_lba_end -
ep[i].ent_lba_start + 1;
if (guid_is_equal(u, &GET_nbsd_ffs))
d->part[j].fstype = FS_BSDFFS;
else if (guid_is_equal(u, &GET_nbsd_lfs))
d->part[j].fstype = FS_BSDLFS;
else if (guid_is_equal(u, &GET_nbsd_raid))
d->part[j].fstype = FS_RAID;
else if (guid_is_equal(u, &GET_nbsd_swap))
d->part[j].fstype = FS_SWAP;
else
d->part[j].fstype = FS_OTHER;
}
}
}
if (crc != gpth.hdr_crc_table) {
#ifdef DISK_DEBUG
printf("GPT table CRC invalid\n");
#endif
return -1;
}
return 0;
}
static int
read_gpt(struct biosdisk *d)
{
struct biosdisk_extinfo ed;
daddr_t gptsector[2];
int i, error;
if (d->ll.type != BIOSDISK_TYPE_HD)
/* No GPT on floppy and CD */
return -1;
gptsector[0] = GPT_HDR_BLKNO;
if (set_geometry(&d->ll, &ed) == 0 && d->ll.flags & BIOSDISK_INT13EXT) {
gptsector[1] = ed.totsec - 1;
d->ll.secsize = ed.sbytes;
} else {
#ifdef DISK_DEBUG
printf("Unable to determine extended disk geometry - "
"using CHS\n");
#endif
/* at least try some other reasonable values then */
gptsector[1] = d->ll.chs_sectors - 1;
}
/*
* Use any valid GPT available, do not require both GPTs to be valid
*/
for (i = 0; i < __arraycount(gptsector); i++) {
error = check_gpt(d, gptsector[i]);
if (error == 0)
break;
}
if (i >= __arraycount(gptsector)) {
memset(d->part, 0, sizeof(d->part));
return -1;
}
#ifdef DISK_DEBUG
printf("using %s GPT\n", (i == 0) ? "primary" : "secondary");
#endif
return 0;
}
#endif /* !NO_GPT */
#ifndef NO_DISKLABEL
static void
ingest_label(struct biosdisk *d, struct disklabel *lp)
{
int part;
memset(d->part, 0, sizeof(d->part));
for (part = 0; part < lp->d_npartitions; part++) {
if (lp->d_partitions[part].p_size == 0)
continue;
if (lp->d_partitions[part].p_fstype == FS_UNUSED)
continue;
d->part[part].fstype = lp->d_partitions[part].p_fstype;
d->part[part].offset = lp->d_partitions[part].p_offset;
d->part[part].size = lp->d_partitions[part].p_size;
}
}
static int
check_label(struct biosdisk *d, daddr_t sector)
{
struct disklabel *lp;
/* find partition in NetBSD disklabel */
if (readsects(&d->ll, sector + LABELSECTOR, 1, d->buf, 0)) {
#ifdef DISK_DEBUG
printf("Error reading disklabel\n");
#endif
return EIO;
}
lp = (struct disklabel *) (d->buf + LABELOFFSET);
if (lp->d_magic != DISKMAGIC || dkcksum(lp)) {
#ifdef DISK_DEBUG
printf("warning: no disklabel in sector %"PRId64"\n", sector);
#endif
return -1;
}
ingest_label(d, lp);
#ifdef _STANDALONE
bi_disk.labelsector = sector + LABELSECTOR;
bi_disk.label.type = lp->d_type;
memcpy(bi_disk.label.packname, lp->d_packname, 16);
bi_disk.label.checksum = lp->d_checksum;
bi_wedge.matchblk = sector + LABELSECTOR;
bi_wedge.matchnblks = 1;
md5(bi_wedge.matchhash, d->buf, d->ll.secsize);
#endif
return 0;
}
static int
read_minix_subp(struct biosdisk *d, struct disklabel* dflt_lbl,
int this_ext, daddr_t sector)
{
struct mbr_partition mbr[MBR_PART_COUNT];
int i;
int typ;
struct partition *p;
if (readsects(&d->ll, sector, 1, d->buf, 0)) {
#ifdef DISK_DEBUG
printf("Error reading MFS sector %d\n", sector);
#endif
return EIO;
}
if ((uint8_t)d->buf[510] != 0x55 || (uint8_t)d->buf[511] != 0xAA) {
return -1;
}
memcpy(&mbr, ((struct mbr_sector *)d->buf)->mbr_parts, sizeof(mbr));
for (i = 0; i < MBR_PART_COUNT; i++) {
typ = mbr[i].mbrp_type;
if (typ == 0)
continue;
sector = this_ext + mbr[i].mbrp_start;
if (dflt_lbl->d_npartitions >= MAXPARTITIONS)
continue;
p = &dflt_lbl->d_partitions[dflt_lbl->d_npartitions++];
p->p_offset = sector;
p->p_size = mbr[i].mbrp_size;
p->p_fstype = xlat_mbr_fstype(typ);
}
return 0;
}
static int
read_label(struct biosdisk *d)
{
struct disklabel dflt_lbl;
struct mbr_partition mbr[MBR_PART_COUNT];
struct partition *p;
int sector, i;
int error;
int typ;
int ext_base, this_ext, next_ext;
#ifdef COMPAT_386BSD_MBRPART
int sector_386bsd = -1;
#endif
memset(&dflt_lbl, 0, sizeof(dflt_lbl));
dflt_lbl.d_npartitions = 8;
d->boff = 0;
if (d->ll.type != BIOSDISK_TYPE_HD)
/* No label on floppy and CD */
return -1;
/*
* find NetBSD Partition in DOS partition table
* XXX check magic???
*/
ext_base = 0;
next_ext = 0;
for (;;) {
this_ext = ext_base + next_ext;
next_ext = 0;
if (readsects(&d->ll, this_ext, 1, d->buf, 0)) {
#ifdef DISK_DEBUG
printf("error reading MBR sector %d\n", this_ext);
#endif
return EIO;
}
memcpy(&mbr, ((struct mbr_sector *)d->buf)->mbr_parts,
sizeof(mbr));
/* Look for NetBSD partition ID */
for (i = 0; i < MBR_PART_COUNT; i++) {
typ = mbr[i].mbrp_type;
if (typ == 0)
continue;
sector = this_ext + mbr[i].mbrp_start;
#ifdef DISK_DEBUG
printf("ptn type %d in sector %d\n", typ, sector);
#endif
if (typ == MBR_PTYPE_MINIX_14B) {
if (!read_minix_subp(d, &dflt_lbl,
this_ext, sector)) {
/* Don't add "container" partition */
continue;
}
}
if (typ == MBR_PTYPE_NETBSD) {
error = check_label(d, sector);
if (error >= 0)
return error;
}
if (MBR_IS_EXTENDED(typ)) {
next_ext = mbr[i].mbrp_start;
continue;
}
#ifdef COMPAT_386BSD_MBRPART
if (this_ext == 0 && typ == MBR_PTYPE_386BSD)
sector_386bsd = sector;
#endif
if (this_ext != 0) {
if (dflt_lbl.d_npartitions >= MAXPARTITIONS)
continue;
p = &dflt_lbl.d_partitions[dflt_lbl.d_npartitions++];
} else
p = &dflt_lbl.d_partitions[i];
p->p_offset = sector;
p->p_size = mbr[i].mbrp_size;
p->p_fstype = xlat_mbr_fstype(typ);
}
if (next_ext == 0)
break;
if (ext_base == 0) {
ext_base = next_ext;
next_ext = 0;
}
}
sector = 0;
#ifdef COMPAT_386BSD_MBRPART
if (sector_386bsd != -1) {
printf("old BSD partition ID!\n");
sector = sector_386bsd;
}
#endif
/*
* One of two things:
* 1. no MBR
* 2. no NetBSD partition in MBR
*
* We simply default to "start of disk" in this case and
* press on.
*/
error = check_label(d, sector);
if (error >= 0)
return error;
/*
* Nothing at start of disk, return info from mbr partitions.
*/
/* XXX fill it to make checksum match kernel one */
dflt_lbl.d_checksum = dkcksum(&dflt_lbl);
ingest_label(d, &dflt_lbl);
return 0;
}
#endif /* NO_DISKLABEL */
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
static int
read_partitions(struct biosdisk *d)
{
int error;
error = -1;
#ifndef NO_GPT
error = read_gpt(d);
if (error == 0)
return 0;
#endif
#ifndef NO_DISKLABEL
error = read_label(d);
#endif
return error;
}
#endif
void
biosdisk_probe(void)
{
struct biosdisk d;
struct biosdisk_extinfo ed;
uint64_t size;
int first;
int i;
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
int part;
#endif
for (i = 0; i < MAX_BIOSDISKS + 2; i++) {
first = 1;
memset(&d, 0, sizeof(d));
memset(&ed, 0, sizeof(ed));
if (i >= MAX_BIOSDISKS)
d.ll.dev = 0x00 + i - MAX_BIOSDISKS; /* fd */
else
d.ll.dev = 0x80 + i; /* hd/cd */
if (set_geometry(&d.ll, &ed))
continue;
printf("disk ");
switch (d.ll.type) {
case BIOSDISK_TYPE_CD:
printf("cd0\n cd0a\n");
break;
case BIOSDISK_TYPE_FD:
printf("fd%d\n", d.ll.dev & 0x7f);
printf(" fd%da\n", d.ll.dev & 0x7f);
break;
case BIOSDISK_TYPE_HD:
printf("hd%d", d.ll.dev & 0x7f);
if (d.ll.flags & BIOSDISK_INT13EXT) {
printf(" size ");
size = ed.totsec * ed.sbytes;
if (size >= (10ULL * 1024 * 1024 * 1024))
printf("%"PRIu64" GB",
size / (1024 * 1024 * 1024));
else
printf("%"PRIu64" MB",
size / (1024 * 1024));
}
printf("\n");
break;
}
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
if (d.ll.type != BIOSDISK_TYPE_HD)
continue;
if (read_partitions(&d) != 0)
continue;
for (part = 0; part < BIOSDISKNPART; part++) {
if (d.part[part].size == 0)
continue;
if (d.part[part].fstype == FS_UNUSED)
continue;
if (first) {
printf(" ");
first = 0;
}
printf(" hd%d%c(", d.ll.dev & 0x7f, part + 'a');
if (d.part[part].fstype < FSMAXTYPES)
printf("%s",
fstypenames[d.part[part].fstype]);
else
printf("%d", d.part[part].fstype);
printf(")");
}
#endif
if (first == 0)
printf("\n");
}
}
/* Determine likely partition for possible sector number of dos
* partition.
*/
int
biosdisk_findpartition(int biosdev, daddr_t sector)
{
#if defined(NO_DISKLABEL) && defined(NO_GPT)
return 0;
#else
struct biosdisk *d;
int partition = 0;
#ifdef DISK_DEBUG
printf("looking for partition device %x, sector %"PRId64"\n", biosdev, sector);
#endif
/* Look for netbsd partition that is the dos boot one */
d = alloc_biosdisk(biosdev);
if (d == NULL)
return 0;
if (read_partitions(d) == 0) {
for (partition = (BIOSDISKNPART-1); --partition;) {
if (d->part[partition].fstype == FS_UNUSED)
continue;
if (d->part[partition].offset == sector)
break;
}
}
dealloc(d, sizeof(*d));
return partition;
#endif /* NO_DISKLABEL && NO_GPT */
}
#ifdef _STANDALONE
static void
add_biosdisk_bootinfo(void)
{
static bool done;
if (bootinfo == NULL) {
done = false;
return;
}
if (done)
return;
BI_ADD(&bi_disk, BTINFO_BOOTDISK, sizeof(bi_disk));
BI_ADD(&bi_wedge, BTINFO_BOOTWEDGE, sizeof(bi_wedge));
done = true;
return;
}
#endif
int
biosdisk_open(struct open_file *f, ...)
/* struct open_file *f, int biosdev, int partition */
{
va_list ap;
struct biosdisk *d;
int biosdev;
int partition;
int error = 0;
va_start(ap, f);
biosdev = va_arg(ap, int);
d = alloc_biosdisk(biosdev);
if (d == NULL) {
error = ENXIO;
goto out;
}
partition = va_arg(ap, int);
#ifdef _STANDALONE
bi_disk.biosdev = d->ll.dev;
bi_disk.partition = partition;
bi_disk.labelsector = -1;
bi_wedge.biosdev = d->ll.dev;
bi_wedge.matchblk = -1;
#endif
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
error = read_partitions(d);
if (error == -1) {
error = 0;
goto nolabel;
}
if (error)
goto out;
if (partition >= BIOSDISKNPART ||
d->part[partition].fstype == FS_UNUSED) {
#ifdef DISK_DEBUG
printf("illegal partition\n");
#endif
error = EPART;
goto out;
}
d->boff = d->part[partition].offset;
if (d->part[partition].fstype == FS_RAID)
d->boff += RF_PROTECTED_SECTORS;
#ifdef _STANDALONE
bi_wedge.startblk = d->part[partition].offset;
bi_wedge.nblks = d->part[partition].size;
#endif
nolabel:
#endif
#ifdef DISK_DEBUG
printf("partition @%"PRId64"\n", d->boff);
#endif
#ifdef _STANDALONE
add_biosdisk_bootinfo();
#endif
f->f_devdata = d;
out:
va_end(ap);
if (error)
dealloc(d, sizeof(*d));
return error;
}
#ifndef LIBSA_NO_FS_CLOSE
int
biosdisk_close(struct open_file *f)
{
struct biosdisk *d = f->f_devdata;
/* let the floppy drive go off */
if (d->ll.type == BIOSDISK_TYPE_FD)
wait_sec(3); /* 2s is enough on all PCs I found */
dealloc(d, sizeof(*d));
f->f_devdata = NULL;
return 0;
}
#endif
int
biosdisk_ioctl(struct open_file *f, u_long cmd, void *arg)
{
return EIO;
}

View file

@ -0,0 +1,32 @@
/* $NetBSD: biosdisk.h,v 1.8 2010/12/24 20:36:51 jakllsch Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
int biosdisk_strategy(void *, int, daddr_t, size_t, void *, size_t *);
int biosdisk_open(struct open_file *, ...);
int biosdisk_close(struct open_file *);
int biosdisk_ioctl(struct open_file *, u_long, void *);
int biosdisk_findpartition(int, daddr_t);

View file

@ -0,0 +1,319 @@
/* $NetBSD: biosdisk_ll.c,v 1.31 2011/02/21 02:58:02 jakllsch Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Bang Jun-Young.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Matthias Drochner.
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* shared by bootsector startup (bootsectmain) and biosdisk.c
* needs lowlevel parts from bios_disk.S
*/
#include <lib/libkern/libkern.h>
#include <lib/libsa/stand.h>
#include "biosdisk_ll.h"
#include "diskbuf.h"
#include "libi386.h"
static int do_read(struct biosdisk_ll *, daddr_t, int, char *);
/*
* we get from get_diskinfo():
* %ah %ch %cl %dh (registers after int13/8), ie
* xxxxxxxx cccccccc CCssssss hhhhhhhh
*/
#define STATUS(di) ((di)>>24)
#define SPT(di) (((di)>>8)&0x3f)
#define HEADS(di) (((di)&0xff)+1)
#define CYL(di) (((((di)>>16)&0xff)|(((di)>>6)&0x300))+1)
#ifndef BIOSDISK_RETRIES
#define BIOSDISK_RETRIES 5
#endif
int
set_geometry(struct biosdisk_ll *d, struct biosdisk_extinfo *ed)
{
int diskinfo;
diskinfo = biosdisk_getinfo(d->dev);
d->sec = SPT(diskinfo);
d->head = HEADS(diskinfo);
d->cyl = CYL(diskinfo);
d->chs_sectors = d->sec * d->head * d->cyl;
if (d->dev >= 0x80 + get_harddrives()) {
d->secsize = 2048;
d->type = BIOSDISK_TYPE_CD;
} else {
d->secsize = 512;
if (d->dev & 0x80)
d->type = BIOSDISK_TYPE_HD;
else
d->type = BIOSDISK_TYPE_FD;
}
/*
* Some broken BIOSes such as one found on Soltek SL-75DRV2 report
* that they don't support int13 extension for CD-ROM drives while
* they actually do. As a workaround, if the boot device is a CD we
* assume that the extension is available. Note that only very old
* BIOSes don't support the extended mode, and they don't work with
* ATAPI CD-ROM drives, either. So there's no problem.
*/
d->flags = 0;
if (d->type == BIOSDISK_TYPE_CD ||
(d->type == BIOSDISK_TYPE_HD && biosdisk_int13ext(d->dev))) {
d->flags |= BIOSDISK_INT13EXT;
if (ed != NULL) {
ed->size = sizeof(*ed);
if (biosdisk_getextinfo(d->dev, ed) != 0)
return -1;
}
}
/*
* If the drive is 2.88MB floppy drive, check that we can actually
* read sector >= 18. If not, assume 1.44MB floppy disk.
*/
if (d->type == BIOSDISK_TYPE_FD && SPT(diskinfo) == 36) {
char buf[512];
if (biosdisk_read(d->dev, 0, 0, 18, 1, buf)) {
d->sec = 18;
d->chs_sectors /= 2;
}
}
return 0;
}
/*
* Global shared "diskbuf" is used as read ahead buffer. For reading from
* floppies, the bootstrap has to be loaded on a 64K boundary to ensure that
* this buffer doesn't cross a 64K DMA boundary.
*/
static int ra_dev;
static daddr_t ra_end;
static daddr_t ra_first;
/*
* Because some older BIOSes have bugs in their int13 extensions, we
* only try to use the extended read if the I/O request can't be addressed
* using CHS.
*
* Of course, some BIOSes have bugs in ths CHS read, such as failing to
* function properly if the MBR table has a different geometry than the
* BIOS would generate internally for the device in question, and so we
* provide a way to force the extended on hard disks via a compile-time
* option.
*/
#if defined(FORCE_INT13EXT)
#define NEED_INT13EXT(d, dblk, num) \
(((d)->dev & 0x80) != 0)
#else
#define NEED_INT13EXT(d, dblk, num) \
(((d)->type == BIOSDISK_TYPE_CD) || \
((d)->type == BIOSDISK_TYPE_HD && \
((dblk) + (num)) >= (d)->chs_sectors))
#endif
static int
do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
{
if (NEED_INT13EXT(d, dblk, num)) {
struct {
int8_t size;
int8_t resvd;
int16_t cnt;
int16_t off;
int16_t seg;
int64_t sec;
} ext;
if (!(d->flags & BIOSDISK_INT13EXT))
return -1;
ext.size = sizeof(ext);
ext.resvd = 0;
ext.cnt = num;
/* seg:off of physical address */
ext.off = (int)buf & 0xf;
ext.seg = vtophys(buf) >> 4;
ext.sec = dblk;
if (biosdisk_extread(d->dev, &ext)) {
(void)biosdisk_reset(d->dev);
return -1;
}
return ext.cnt;
} else {
int cyl, head, sec, nsec, spc, dblk32;
dblk32 = (int)dblk;
spc = d->head * d->sec;
cyl = dblk32 / spc;
head = (dblk32 % spc) / d->sec;
sec = dblk32 % d->sec;
nsec = d->sec - sec;
if (nsec > num)
nsec = num;
if (biosdisk_read(d->dev, cyl, head, sec, nsec, buf)) {
(void)biosdisk_reset(d->dev);
return -1;
}
return nsec;
}
}
/*
* NB if 'cold' is set below not all of the program is loaded, so
* mustn't use data segment, bss, call library functions or do read-ahead.
*/
int
readsects(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf, int cold)
{
#ifdef BOOTXX
#define cold 1 /* collapse out references to diskbufp */
#endif
while (num) {
int nsec;
/* check for usable data in read-ahead buffer */
if (cold || diskbuf_user != &ra_dev || d->dev != ra_dev
|| dblk < ra_first || dblk >= ra_end) {
/* no, read from disk */
char *trbuf;
int maxsecs;
int retries = BIOSDISK_RETRIES;
if (cold) {
/* transfer directly to buffer */
trbuf = buf;
maxsecs = num;
} else {
/* fill read-ahead buffer */
trbuf = alloc_diskbuf(0); /* no data yet */
maxsecs = DISKBUFSIZE / d->secsize;
}
while ((nsec = do_read(d, dblk, maxsecs, trbuf)) < 0) {
#ifdef DISK_DEBUG
if (!cold)
printf("read error dblk %"PRId64"-%"PRId64"\n",
dblk, (dblk + maxsecs - 1));
#endif
if (--retries >= 0)
continue;
return -1; /* XXX cannot output here if
* (cold) */
}
if (!cold) {
ra_dev = d->dev;
ra_first = dblk;
ra_end = dblk + nsec;
diskbuf_user = &ra_dev;
}
} else /* can take blocks from end of read-ahead
* buffer */
nsec = ra_end - dblk;
if (!cold) {
/* copy data from read-ahead to user buffer */
if (nsec > num)
nsec = num;
memcpy(buf,
diskbufp + (dblk - ra_first) * d->secsize,
nsec * d->secsize);
}
buf += nsec * d->secsize;
num -= nsec;
dblk += nsec;
}
return 0;
}
/*
* Return the number of hard disk drives.
*/
int
get_harddrives(void)
{
/*
* Some BIOSes are buggy so that they return incorrect number
* of hard drives with int13/ah=8. We read a byte at 0040:0075
* instead, which is known to be always correct.
*/
int n = 0;
pvbcopy((void *)0x475, &n, 1);
return n;
}

View file

@ -0,0 +1,126 @@
/* $NetBSD: biosdisk_ll.h,v 1.15 2007/12/25 18:33:34 perry Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Matthias Drochner.
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* shared by bootsector startup (bootsectmain) and biosdisk.c needs lowlevel
* parts from bios_disk.S
*/
/*
* Beware that bios_disk.S relies on the offsets of the structure
* members.
*/
struct biosdisk_ll {
int dev; /* BIOS device number */
int type; /* device type; see below */
int sec, head, cyl; /* geometry */
int flags; /* see below */
int chs_sectors; /* # of sectors addressable by CHS */
int secsize; /* bytes per sector */
};
#define BIOSDISK_INT13EXT 1 /* BIOS supports int13 extension */
#define BIOSDISK_TYPE_FD 0
#define BIOSDISK_TYPE_HD 1
#define BIOSDISK_TYPE_CD 2
/*
* Version 1.x drive parameters from int13 extensions
* - should be supported by every BIOS that supports the extensions.
* Version 3.x parameters allow the drives to be matched properly
* - but are much less likely to be supported.
*/
struct biosdisk_extinfo {
uint16_t size; /* size of buffer, set on call */
uint16_t flags; /* flags, see below */
uint32_t cyl; /* # of physical cylinders */
uint32_t head; /* # of physical heads */
uint32_t sec; /* # of physical sectors per track */
uint64_t totsec; /* total number of sectors */
uint16_t sbytes; /* # of bytes per sector */
#if defined(BIOSDISK_EXTINFO_V2) || defined(BIOSDISK_EXTINFO_V3)
/* v2.0 extensions */
uint32_t edd_cfg; /* EDD configuration parameters */
#if defined(BIOSDISK_EXTINFO_V3)
/* v3.0 extensions */
uint16_t devpath_sig; /* 0xbedd if path info present */
#define EXTINFO_DEVPATH_SIGNATURE 0xbedd
uint8_t devpath_len; /* length from devpath_sig */
uint8_t fill21[3];
char host_bus[4]; /* Probably "ISA" or "PCI" */
char iface_type[8]; /* "ATA", "ATAPI", "SCSI" etc */
union {
uint8_t ip_8[8];
uint16_t ip_16[4];
uint32_t ip_32[2];
uint64_t ip_64[1];
} interface_path;
#define ip_isa_iobase ip_16[0]; /* iobase for ISA bus */
#define ip_pci_bus ip_8[0]; /* PCI bus number */
#define ip_pci_device ip_8[1]; /* PCI device number */
#define ip_pci_function ip_8[2]; /* PCI function number */
union {
uint8_t dp_8[8];
uint16_t dp_16[4];
uint32_t dp_32[2];
uint64_t dp_64[1];
} device_path;
#define dp_ata_slave dp_8[0];
#define dp_atapi_slave dp_8[0];
#define dp_atapi_lun dp_8[1];
#define dp_scsi_lun dp_8[0];
#define dp_firewire_guid dp_64[0];
#define dp_fibrechnl_wwn dp_64[0];
uint8_t fill40[1];
uint8_t checksum; /* byte sum from dev_path_sig is 0 */
#endif /* BIOSDISK_EXTINFO_V3 */
#endif /* BIOSDISK_EXTINFO_V2 */
} __packed;
#define EXTINFO_DMA_TRANS 0x0001 /* transparent DMA boundary errors */
#define EXTINFO_GEOM_VALID 0x0002 /* geometry in c/h/s in struct valid */
#define EXTINFO_REMOVABLE 0x0004 /* removable device */
#define EXTINFO_WRITEVERF 0x0008 /* supports write with verify */
#define EXTINFO_CHANGELINE 0x0010 /* changeline support */
#define EXTINFO_LOCKABLE 0x0020 /* device is lockable */
#define EXTINFO_MAXGEOM 0x0040 /* geometry set to max; no media */
#define BIOSDISK_DEFAULT_SECSIZE 512
int set_geometry(struct biosdisk_ll *, struct biosdisk_extinfo *);
int readsects(struct biosdisk_ll *, daddr_t, int, char *, int);

View file

@ -0,0 +1,58 @@
/* $NetBSD: biosgetrtc.S,v 1.7 2011/06/16 13:27:59 joerg Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
ENTRY(biosgetrtc)
pusha
pushl %eax
xorl %ebx, %ebx
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $2, %ah
int $0x1a
jnc ok
movl $-1, %ebx
ok:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
popl %eax
movb %ch, (%eax)
movb %cl, 1(%eax)
movb %dh, 2(%eax)
movb $0, 3(%eax)
movl %ebx, 28(%esp)
popa
ret

View file

@ -0,0 +1,54 @@
/* $NetBSD: biosgetsystime.S,v 1.3 2011/06/16 13:27:59 joerg Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
/* Return system time (~18.2Hz ticks since midnight) */
ENTRY(biosgetsystime)
pusha
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0, %ah
int $0x1a
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
mov %ecx, %eax
shl $16, %eax
movw %dx, %ax
movl %eax, 28(%esp)
popa
ret

View file

@ -0,0 +1,117 @@
/* $NetBSD: biosmca.S,v 1.4 2003/02/01 14:48:18 dsl Exp $ */
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* 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.
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* extracted from netbsd:sys/arch/i386/stand/bios_disk.S */
#include <machine/asm.h>
.data
.globl _C_LABEL(biosmca_ps2model)
_C_LABEL(biosmca_ps2model): .long 0
.text
/*
# BIOS call "INT 0x15 Function 0xc0" to read extended sys config info on PS/2
# Return: no return value
#
# This function initializes biosmca_ps2model with model number as
# identified by BIOS, if the machine is a PS/2 box (i.e. has MCA bus
# instead of ISA).
*/
ENTRY(biosmca)
.code32
pushl %ebp
movl %esp, %ebp
pushl %ebx
push %ecx
push %edx
push %esi
push %edi
push %eax
call _C_LABEL(prot_to_real) # enter real mode
.code16
# zero %ecx
xorl %ecx, %ecx
xor %ax, %ax
movb $0xc0, %ah # subfunction
int $0x15
jc back
# check feature byte 1 if MCA bus present and replaces ISA
movb %es:5(%bx), %al
andb $0x02, %al # bit 1 set means MCA instead of ISA
# see also arch/i386/mca/mca_machdep.c
jnz back
# save model and submodel bytes to %cx
movb %es:2(%bx), %ch # model (1 byte)
movb %es:3(%bx), %cl # submodel (1 byte)
back:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
# save model
movl %ecx, _C_LABEL(biosmca_ps2model)
pop %eax
pop %edi
pop %esi
pop %edx
pop %ecx
popl %ebx
popl %ebp
ret

View file

@ -0,0 +1,31 @@
/* $NetBSD: biosmca.h,v 1.3 2008/12/14 17:03:43 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
void biosmca(void);
extern int biosmca_ps2model;

View file

@ -0,0 +1,78 @@
/* $NetBSD: biosmem.S,v 1.9 2011/06/16 13:27:59 joerg Exp $ */
/*
* Copyright (c) 1996
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
.text
/* get mem below 1M, in kByte */
ENTRY(getbasemem)
pusha
call _C_LABEL(prot_to_real)
.code16
int $0x12
# zero-extend 16-bit result to 32 bits.
movzwl %ax, %eax
calll _C_LABEL(real_to_prot)
.code32
movl %eax, 28(%esp)
popa
ret
/* get mem above 1M, in kByte */
ENTRY(getextmem1)
pusha
call _C_LABEL(prot_to_real)
.code16
movb $0x88,%ah
int $0x15
# zero-extend 16-bit result to 32 bits.
movzwl %ax, %eax
calll _C_LABEL(real_to_prot)
.code32
movl %eax, 28(%esp)
popa
ret

View file

@ -0,0 +1,87 @@
/* $NetBSD: biosmemps2.S,v 1.6 2011/06/16 13:27:59 joerg Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jaromir Dolecek.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
.text
/* int getextmemp2(void buffer)
call int 15 function 0xc7 - later PS/2s - RETURN MEMORY-MAP INFORMATION
return: 0=OK, nonzero=error
buffer: filled with memory-map table structure
*/
ENTRY(getextmemps2)
.code32
movl %eax, %edx
xorl %eax, %eax
pusha
call _C_LABEL(prot_to_real)
.code16
# do int15, function 0xc0 call to discover if C7h is supported
movb $0xc0, %ah
int $0x15
setc %cl
jc out # 0xc0 not supported if carry set
# check feature byte 2, bit 4 to see if return memory map is supported
movb %es:6(%bx), %al
andb $0x10, %al
jnz getmem # 0xc7 supported
# set %cl to indicate failure, and exit
movb $2, %cl
jmp out
getmem:
# move the parameter to right register
push %ds
movl %edx, %esi
andl $0xf, %esi
shrl $4, %edx
mov %ds, %ax
add %dx, %ax
mov %ax, %ds
# actually call int15, function 0xc7 now
movb $0xc7, %ah
int $0x15
setc %cl # save carry
pop %ds
out:
calll _C_LABEL(real_to_prot)
.code32
movb %cl, 28(%esp)
popa
ret

View file

@ -0,0 +1,167 @@
/* $NetBSD: biosmemx.S,v 1.9 2008/10/14 14:18:11 ad Exp $ */
/*
* Copyright (c) 1997, 1999
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
.text
/* int getextmem2(int buffer[2])
return: 0=OK, -1=error
buffer[0]: extmem kBytes below 16M (max 15M/1024)
buffer[1]: extmem above 16M, in 64k units
*/
ENTRY(getextmem2)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
call _C_LABEL(prot_to_real)
.code16
xorl %ebx, %ebx
movl $0xe801, %eax
int $0x15
pushf
movw %si, %ax
orw %si, %bx
jz 1f /* if zero use configured values */
movw %cx, %ax /* k below 16M (max 0x3c00 = 15MB) */
movw %dx, %bx /* 64k above 16M */
1:
popf
setc %bl
calll _C_LABEL(real_to_prot)
.code32
movl 8(%ebp), %edi
xorl %eax, %eax
movw %cx, %ax
stosl
movw %dx, %ax
stosl
movb %bl, %al
cbw
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/* int getmementry(int *iterator, buffer[5])
return: 0=ok, else error
buffer[0]: start of memory chunk
buffer[2]: length (bytes)
buffer[4]: type
*/
ENTRY(getmementry)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
movl 8(%ebp), %eax
movl 0(%eax), %ebx /* index */
movl $20, %ecx /* Buffer size */
movl $0x534d4150, %edx /* "SMAP" */
movl 12(%ebp), %edi /* buffer address */
call _C_LABEL(prot_to_real)
.code16
push %di
shrl $4, %edi
mov %ds, %ax
add %di, %ax
mov %ax, %es
pop %di
and $0xf, %di /* buffer addres now in ES:DI */
movl $0xe820, %eax /* Some BIOS check EAX value */
int $0x15
setc %cl
calll _C_LABEL(real_to_prot)
.code32
movl 8(%ebp), %eax
movl %ebx, 0(%eax) /* updated index */
xorl %eax, %eax
movb %cl, %al
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/* int biosA20(void)
return: 0=ok, else error
*/
ENTRY(biosA20)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
call _C_LABEL(prot_to_real)
.code16
movl $0x2401, %eax
int $0x15
setc %cl
calll _C_LABEL(real_to_prot)
.code32
movzbl %cl, %eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret

View file

@ -0,0 +1,96 @@
/* $NetBSD: biospci.c,v 1.5 2008/12/14 17:03:43 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* basic PCI functions for libsa needs lowlevel parts from bios_pci.S
*/
#include <lib/libsa/stand.h>
#include "pcivar.h"
extern int pcibios_present(int *);
extern int pcibios_finddev(int, int, int, unsigned int *);
extern int pcibios_cfgread(unsigned int, int, int *);
extern int pcibios_cfgwrite(unsigned int, int, int);
#define PCISIG ('P' | ('C' << 8) | ('I' << 16) | (' ' << 24))
int
pcicheck(void)
{
int ret, sig;
ret = pcibios_present(&sig);
if ((ret & 0xff00) || (sig != PCISIG))
return -1;
return 0;
}
int
pcifinddev(int vid, int did, pcihdl_t *handle)
{
int ret;
*handle = 0;
ret = pcibios_finddev(vid, did, 0, handle);
if (ret)
return -1;
return 0;
}
int
pcicfgread(pcihdl_t *handle, int off, int *val)
{
int ret;
ret = pcibios_cfgread(*handle, off, val);
if (ret)
return -1;
return 0;
}
int
pcicfgwrite(pcihdl_t *handle, int off, int val)
{
int ret;
ret = pcibios_cfgwrite(*handle, off, val);
if (ret)
return -1;
return 0;
}

View file

@ -0,0 +1,57 @@
/* $NetBSD: biosreboot.S,v 1.5 2011/06/16 13:27:59 joerg Exp $ */
/*
* Copyright (c) 1997
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
.text
/* Call INT 19 to do the equivalent of CTL-ALT-DEL */
ENTRY(reboot)
pusha
call _C_LABEL(prot_to_real)
.code16
int $0x19
/* NOTE: We should never even get past this point. */
calll _C_LABEL(real_to_prot)
.code32
movl %ebx, 28(%esp)
popa
ret

View file

@ -0,0 +1,358 @@
/* $NetBSD: biosvbe.S,v 1.3 2011/02/20 22:03:13 jakllsch Exp $ */
/*-
* Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca>
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
.text
/*
* VESA BIOS Extensions routines
*/
/*
* Function 00h - Return VBE Controller Information
*
* int biosvbe_info(struct vbeinfoblock *)
* return: VBE call status
*/
ENTRY(biosvbe_info)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
movl 8(%ebp), %edi /* vbe info block address*/
call _C_LABEL(prot_to_real)
.code16
push %es
push %di
shrl $4, %edi
mov %ds, %ax
add %di, %ax
mov %ax, %es
pop %di
and $0xf, %di /* mode info block address now in es:di */
movw $0x4f00, %ax /* get vbe info block */
int $0x10
pop %es
calll _C_LABEL(real_to_prot)
.code32
andl $0xffff,%eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/*
* Function 01h - Return VBE Mode Information
*
* int biosvbe_get_mode_info(int mode, struct modeinfoblock *mi)
* return: VBE call status
*/
ENTRY(biosvbe_get_mode_info)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
movl 8(%ebp), %ecx /* mode number */
movl 12(%ebp), %edi /* mode info block address */
call _C_LABEL(prot_to_real)
.code16
push %es
push %di
shrl $4, %edi
mov %ds, %ax
add %di, %ax
mov %ax, %es
pop %di
and $0xf, %di /* mode info block address now in es:di */
movw $0x4f01, %ax /* get mode info block */
int $0x10
pop %es
calll _C_LABEL(real_to_prot)
.code32
andl $0xffff,%eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/*
* Function 02h - Set VBE Mode
*
* int biosvbe_set_mode(int mode)
* return: VBE call status
*/
ENTRY(biosvbe_set_mode)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
movl 8(%ebp), %ebx /* mode number */
orl $0x4000, %ebx
call _C_LABEL(prot_to_real)
.code16
movw $0x4f02, %ax /* set mode */
int $0x10
calll _C_LABEL(real_to_prot)
.code32
andl $0xffff,%eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/*
* Function 08h - Set/Get DAC Palette Format
*
* int biosvbe_palette_format(int format)
* return: VBE call status
*/
ENTRY(biosvbe_palette_format)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
movl 8(%ebp), %ebx /* mode number */
call _C_LABEL(prot_to_real)
.code16
movw $0x4f08, %ax /* get/set palette format */
int $0x10
calll _C_LABEL(real_to_prot)
.code32
andl $0xffff,%eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/*
* Function 09h - Set/Get Palette Data
*
* int biosvbe_palette_data(int mode, int reg, struct paletteentry *)
* return: VBE call status
*/
ENTRY(biosvbe_palette_data)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
movl 8(%ebp), %ebx /* mode number */
movl 12(%ebp), %edx /* register */
movl 16(%ebp), %edi /* palette entry address */
movl $1, %ecx /* # palette entries to update */
call _C_LABEL(prot_to_real)
.code16
push %es
push %di
shrl $4, %edi
mov %ds, %ax
add %di, %ax
mov %ax, %es
pop %di
and $0xf, %di /* palette entry address now in es:di */
movw $0x4f09, %ax /* get/set palette entry */
int $0x10
pop %es
calll _C_LABEL(real_to_prot)
.code32
andl $0xffff,%eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/*
* Function 15h BL=00h - Report VBE/DDC Capabilities
*
* int biosvbe_ddc_caps(void)
* return: VBE/DDC capabilities
*/
ENTRY(biosvbe_ddc_caps)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
call _C_LABEL(prot_to_real)
.code16
pushw %es
xorw %di, %di
movw %di, %es /* es:di == 0:0 */
movw $0x4f15, %ax /* display identification extensions */
mov $0x00, %bx /* report DDC capabilities */
mov $0x00, %cx /* controller unit number (00h = primary) */
int $0x10
popw %es
calll _C_LABEL(real_to_prot)
.code32
movl %eax,%ecx
movl $0x0000,%eax
andl $0xffff,%ecx
cmpl $0x004f,%ecx
jne 1f
andl $0xffff,%ebx
movl %ebx,%eax
1:
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
/*
* Function 15h BL=01h - Read EDID
*
* int biosvbe_ddc_read_edid(int blockno, void *buf)
* return: VBE call status
*/
ENTRY(biosvbe_ddc_read_edid)
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
push %esi
push %edi
movl 8(%ebp), %edx /* EDID block number */
movl 12(%ebp), %edi /* EDID block address */
call _C_LABEL(prot_to_real)
.code16
push %es
push %di
shrl $4, %edi
mov %ds, %ax
add %di, %ax
mov %ax, %es
pop %di
and $0xf, %di /* EDID block address now in es:di */
movw $0x4f15, %ax /* display identification extensions */
mov $0x01, %bx /* read EDID */
mov $0x00, %cx /* controller unit number (00h = primary) */
int $0x10
pop %es
calll _C_LABEL(real_to_prot)
.code32
andl $0xffff,%eax
pop %edi
pop %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret

View file

@ -0,0 +1,65 @@
/* $NetBSD: biosvideomode.S,v 1.3 2003/04/16 13:49:21 dsl Exp $ */
/*
* Copyright (c) 1996
* Perry E. Metzger. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/asm.h>
.text
ENTRY(biosvideomode)
pushl %ebp
movl %esp,%ebp
pushl %ebx
push %esi
push %edi
call _C_LABEL(prot_to_real)
.code16
movb $0, %ah
movb $2, %al
int $0x10
# zero-extend 16-bit result to 32 bits.
movl $0, %ebx
movw %ax,%bx
calll _C_LABEL(real_to_prot)
.code32
movl %ebx, %eax
pop %edi
pop %esi
popl %ebx
popl %ebp
ret

View file

@ -0,0 +1,15 @@
/* $NetBSD: boot_params.S,v 1.6 2010/01/17 14:54:44 drochner Exp $ */
/* Default boot parameters - must match struct x86_boot_params in bootblock.h */
#ifdef BOOTPARAM_DEFFLAGS
.long BOOTPARAM_DEFFLAGS
#else
.long 0x0
#endif
.long 5 /* timeout in seconds */
.long 0 /* console device 0 => CONSDEV_PC */
.long 9600 /* serial baud rate */
.space 16 /* md5 boot password */
.space 64 /* keyboard xlat map */
.long 0 /* console ioaddr */

View file

@ -0,0 +1,45 @@
/* $NetBSD: bootinfo.c,v 1.5 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include "libi386.h"
#include "bootinfo.h"
struct bootinfo *bootinfo;
void
bi_add(struct btinfo_common *what, int type, int size)
{
what->len = size;
what->type = type;
if (bootinfo)
bootinfo->entry[bootinfo->nentries++] = vtophys(what);
}

View file

@ -0,0 +1,48 @@
/* $NetBSD: bootinfo.h,v 1.9 2006/01/25 18:28:26 christos Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <machine/bootinfo.h>
struct bootinfo {
int nentries;
physaddr_t entry[1];
};
extern struct bootinfo *bootinfo;
#define BI_ALLOC(max) (bootinfo = alloc(sizeof(struct bootinfo) \
+ ((max) - 1) * sizeof(physaddr_t))) \
->nentries = 0
#define BI_FREE() dealloc(bootinfo, 0)
#define BI_ADD(x, type, size) bi_add((struct btinfo_common *)(x), type, size)
void bi_add(struct btinfo_common *, int, int);
void bi_getbiosgeom(void);
void bi_getmemmap(void);

View file

@ -0,0 +1,181 @@
/* $NetBSD: bootinfo_biosgeom.c,v 1.21 2010/12/25 01:19:33 jakllsch Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/types.h>
#include <machine/disklabel.h>
#include <machine/cpu.h>
#include <lib/libkern/libkern.h>
#include <lib/libsa/stand.h>
#include "libi386.h"
#include "biosdisk_ll.h"
#include "bootinfo.h"
#ifdef BIOSDISK_EXTINFO_V3
static struct {
char *name;
int flag;
} bus_names[] = { {"ISA", BI_GEOM_BUS_ISA},
{"PCI", BI_GEOM_BUS_PCI},
{NULL, BI_GEOM_BUS_OTHER} };
static struct {
char *name;
int flag;
} iface_names[] = { {"ATA", BI_GEOM_IFACE_ATA},
{"ATAPI", BI_GEOM_IFACE_ATAPI},
{"SCSI", BI_GEOM_IFACE_SCSI},
{"USB", BI_GEOM_IFACE_USB},
{"1394", BI_GEOM_IFACE_1394},
{"FIBRE", BI_GEOM_IFACE_FIBRE},
{NULL, BI_GEOM_IFACE_OTHER} };
#endif
void
bi_getbiosgeom(void)
{
struct btinfo_biosgeom *bibg;
int i, j, nvalid;
int nhd;
unsigned int cksum;
struct biosdisk_ll d;
struct biosdisk_extinfo ed;
char buf[BIOSDISK_DEFAULT_SECSIZE];
nhd = get_harddrives();
#ifdef GEOM_DEBUG
printf("nhd %d\n", nhd);
#endif
bibg = alloc(sizeof(struct btinfo_biosgeom)
+ (nhd - 1) * sizeof(struct bi_biosgeom_entry));
if (bibg == NULL)
return;
for (i = nvalid = 0; i < MAX_BIOSDISKS && nvalid < nhd; i++) {
d.dev = 0x80 + i;
if (set_geometry(&d, &ed))
continue;
memset(&bibg->disk[nvalid], 0, sizeof(bibg->disk[nvalid]));
bibg->disk[nvalid].sec = d.sec;
bibg->disk[nvalid].head = d.head;
bibg->disk[nvalid].cyl = d.cyl;
bibg->disk[nvalid].dev = d.dev;
if (readsects(&d, 0, 1, buf, 0)) {
bibg->disk[nvalid].flags |= BI_GEOM_INVALID;
nvalid++;
continue;
}
#ifdef GEOM_DEBUG
printf("#%d: %x: C %d H %d S %d\n", nvalid,
d.dev, d.cyl, d.head, d.sec);
printf(" sz %d fl %x cyl %d head %d sec %d totsec %"PRId64" sbytes %d\n",
ed.size, ed.flags, ed.cyl, ed.head, ed.sec,
ed.totsec, ed.sbytes);
#endif
if (d.flags & BIOSDISK_INT13EXT) {
bibg->disk[nvalid].totsec = ed.totsec;
bibg->disk[nvalid].flags |= BI_GEOM_EXTINT13;
}
#ifdef BIOSDISK_EXTINFO_V3
#ifdef GEOM_DEBUG
printf(" edd_cfg %x, sig %x, len %x, bus %s type %s\n",
ed.edd_cfg, ed.devpath_sig, ed.devpath_len,
ed.host_bus, ed.iface_type);
#endif
/* The v3.0 stuff will help identify the disks */
if (ed.size >= offsetof(struct biosdisk_ext13info, checksum)
&& ed.devpath_sig == EXTINFO_DEVPATH_SIGNATURE) {
char *cp;
for (cp = (void *)&ed.devpath_sig, cksum = 0;
cp <= (char *)&ed.checksum; cp++) {
cksum += *cp;
}
if ((cksum & 0xff) != 0)
bibg->disk[nvalid].flags |= BI_GEOM_BADCKSUM;
#ifdef GEOM_DEBUG
printf("checksum %x\n", cksum & 0xff);
#endif
for (j = 0; ; j++) {
cp = bus_names[j].name;
if (cp == NULL)
break;
if (strncmp(cp, ed.host_bus,
sizeof(ed.host_bus)) == 0)
break;
}
#ifdef GEOM_DEBUG
printf("bus %s (%x)\n", cp ? cp : "null",
bus_names[j].flag);
#endif
bibg->disk[nvalid].flags |= bus_names[j].flag;
for (j = 0; ; j++) {
cp = iface_names[j].name;
if (cp == NULL)
break;
if (strncmp(cp, ed.iface_type,
sizeof(ed.iface_type)) == 0)
break;
}
bibg->disk[nvalid].flags |= iface_names[j].flag;
/* Dump raw interface path and device path */
bibg->disk[nvalid].interface_path =
ed.interface_path.ip_32[0];
bibg->disk[nvalid].device_path =
ed.device_path.dp_64[0];
#ifdef GEOM_DEBUG
printf("device %s (%x) interface %x path %llx\n",
cp ? cp : "null",
iface_names[j].flag,
ed.interface_path.ip_32[0],
ed.device_path.dp_64[0]);
#endif
}
#endif
for (j = 0, cksum = 0; j < BIOSDISK_DEFAULT_SECSIZE; j++)
cksum += buf[j];
bibg->disk[nvalid].cksum = cksum;
memcpy(bibg->disk[nvalid].dosparts, &buf[MBR_PART_OFFSET],
sizeof(bibg->disk[nvalid].dosparts));
nvalid++;
}
bibg->num = nvalid;
BI_ADD(bibg, BTINFO_BIOSGEOM, sizeof(struct btinfo_biosgeom)
+ nvalid * sizeof(struct bi_biosgeom_entry));
}

View file

@ -0,0 +1,61 @@
/* $NetBSD: bootinfo_memmap.c,v 1.5 2008/12/14 17:03:43 christos Exp $ */
/*
* Copyright (c) 1999
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <lib/libsa/stand.h>
#include "libi386.h"
#include "bootinfo.h"
extern int getmementry(int *, int *);
void
bi_getmemmap(void)
{
int buf[5], i, nranges, n;
struct btinfo_memmap *bimm;
nranges = 0;
i = 0;
do {
if (getmementry(&i, buf))
break;
nranges++;
} while (i);
bimm = alloc(sizeof(struct btinfo_memmap)
+ (nranges - 1) * sizeof(struct bi_memmap_entry));
i = 0;
for (n = 0; n < nranges; n++) {
getmementry(&i, buf);
memcpy(&bimm->entry[n], buf, sizeof(struct bi_memmap_entry));
}
bimm->num = nranges;
BI_ADD(bimm, BTINFO_MEMMAP, sizeof(struct btinfo_memmap)
+ (nranges - 1) * sizeof(struct bi_memmap_entry));
}

View file

@ -0,0 +1,386 @@
/* $NetBSD: bootmenu.c,v 1.10 2011/08/18 13:20:04 christos Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef SMALL
#include <sys/types.h>
#include <sys/reboot.h>
#include <sys/bootblock.h>
#include <lib/libsa/stand.h>
#include <lib/libsa/ufs.h>
#include <lib/libkern/libkern.h>
#include <libi386.h>
#include <bootmenu.h>
#define isnum(c) ((c) >= '0' && (c) <= '9')
extern struct x86_boot_params boot_params;
extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[];
#define MENUFORMAT_AUTO 0
#define MENUFORMAT_NUMBER 1
#define MENUFORMAT_LETTER 2
struct bootconf_def bootconf;
int
atoi(const char *in)
{
char *c;
int ret;
ret = 0;
c = (char *)in;
if (*c == '-')
c++;
for (; isnum(*c); c++)
ret = (ret * 10) + (*c - '0');
return (*in == '-') ? -ret : ret;
}
/*
* This function parses a boot.cfg file in the root of the filesystem
* (if present) and populates the global boot configuration.
*
* The file consists of a number of lines each terminated by \n
* The lines are in the format keyword=value. There should not be spaces
* around the = sign.
*
* The recognised keywords are:
* banner: text displayed instead of the normal welcome text
* menu: Descriptive text:command to use
* timeout: Timeout in seconds (overrides that set by installboot)
* default: the default menu option to use if Return is pressed
* consdev: the console device to use
* format: how menu choices are displayed: (a)utomatic, (n)umbers or (l)etters
* clear: whether to clear the screen or not
*
* Example boot.cfg file:
* banner=Welcome to NetBSD
* banner=Please choose the boot type from the following menu
* menu=Boot NetBSD:boot netbsd
* menu=Boot into single user mode:boot netbsd -s
* menu=:boot hd1a:netbsd -cs
* menu=Goto boot comand line:prompt
* timeout=10
* consdev=com0
* default=1
*/
void
parsebootconf(const char *conf)
{
char *bc, *c;
int cmenu, cbanner, len;
int fd, err, off;
struct stat st;
char *next, *key, *value, *v2;
/* Clear bootconf structure */
memset((void *)&bootconf, 0, sizeof(bootconf));
/* Set timeout to configured */
bootconf.timeout = boot_params.bp_timeout;
/* automatically switch between letter and numbers on menu */
bootconf.menuformat = MENUFORMAT_AUTO;
fd = open(BOOTCONF, 0);
if (fd < 0)
return;
err = fstat(fd, &st);
if (err == -1) {
close(fd);
return;
}
/*
* Check the size. A bootconf file is normally only a few
* hundred bytes long. If it is much bigger than expected,
* don't try to load it. We can't load something big into
* an 8086 real mode segment anyway, and in pxeboot this is
* probably a case of the loader getting a filename for the
* kernel and thinking it is boot.cfg by accident. (The 32k
* number is arbitrary but 8086 real mode data segments max
* out at 64k.)
*/
if (st.st_size > 32768) {
close(fd);
return;
}
bc = alloc(st.st_size + 1);
if (bc == NULL) {
printf("Could not allocate memory for boot configuration\n");
return;
}
off = 0;
do {
len = read(fd, bc + off, 1024);
if (len <= 0)
break;
off += len;
} while (len > 0);
bc[off] = '\0';
close(fd);
/* bc now contains the whole boot.cfg file */
cmenu = 0;
cbanner = 0;
for (c = bc; *c; c = next) {
key = c;
/* find end of line */
for (; *c && *c != '\n'; c++)
/* zero terminate line on start of comment */
if (*c == '#')
*c = 0;
/* zero terminate line */
if (*(next = c))
*next++ = 0;
/* Look for = separator between key and value */
for (c = key; *c && *c != '='; c++)
continue;
/* Ignore lines with no key=value pair */
if (*c == '\0')
continue;
/* zero terminate key which points to keyword */
*c++ = 0;
value = c;
/* Look for end of line (or file) and zero terminate value */
for (; *c && *c != '\n'; c++)
continue;
*c = 0;
if (!strncmp(key, "menu", 4)) {
/*
* Parse "menu=<description>:<command>". If the
* description is empty ("menu=:<command>)",
* then re-use the command as the description.
* Note that the command may contain embedded
* colons.
*/
if (cmenu >= MAXMENU)
continue;
bootconf.desc[cmenu] = value;
for (v2 = value; *v2 && *v2 != ':'; v2++)
continue;
if (*v2) {
*v2++ = 0;
bootconf.command[cmenu] = v2;
if (! *value)
bootconf.desc[cmenu] = v2;
cmenu++;
} else {
/* No delimiter means invalid line */
bootconf.desc[cmenu] = NULL;
}
} else if (!strncmp(key, "banner", 6)) {
if (cbanner < MAXBANNER)
bootconf.banner[cbanner++] = value;
} else if (!strncmp(key, "timeout", 7)) {
if (!isnum(*value))
bootconf.timeout = -1;
else
bootconf.timeout = atoi(value);
} else if (!strncmp(key, "default", 7)) {
bootconf.def = atoi(value) - 1;
} else if (!strncmp(key, "consdev", 7)) {
bootconf.consdev = value;
} else if (!strncmp(key, "load", 4)) {
module_add(value);
} else if (!strncmp(key, "format", 6)) {
printf("value:%c\n", *value);
switch (*value) {
case 'a':
case 'A':
bootconf.menuformat = MENUFORMAT_AUTO;
break;
case 'n':
case 'N':
case 'd':
case 'D':
bootconf.menuformat = MENUFORMAT_NUMBER;
break;
case 'l':
case 'L':
bootconf.menuformat = MENUFORMAT_LETTER;
break;
}
} else if (!strncmp(key, "clear", 5)) {
bootconf.clear = !!atoi(value);
} else if (!strncmp(key, "userconf", 8)) {
userconf_add(value);
}
}
switch (bootconf.menuformat) {
case MENUFORMAT_AUTO:
if (cmenu > 9 && bootconf.timeout > 0)
bootconf.menuformat = MENUFORMAT_LETTER;
else
bootconf.menuformat = MENUFORMAT_NUMBER;
break;
case MENUFORMAT_NUMBER:
if (cmenu > 9 && bootconf.timeout > 0)
cmenu = 9;
break;
}
bootconf.nummenu = cmenu;
if (bootconf.def < 0)
bootconf.def = 0;
if (bootconf.def >= cmenu)
bootconf.def = cmenu - 1;
}
/*
* doboottypemenu will render the menu and parse any user input
*/
static int
getchoicefrominput(char *input, int def)
{
int choice, usedef;
choice = -1;
usedef = 0;
if (*input == '\0' || *input == '\r' || *input == '\n') {
choice = def;
usedef = 1;
} else if (*input >= 'A' && *input < bootconf.nummenu + 'A')
choice = (*input) - 'A';
else if (*input >= 'a' && *input < bootconf.nummenu + 'a')
choice = (*input) - 'a';
else if (isnum(*input)) {
choice = atoi(input) - 1;
if (choice < 0 || choice >= bootconf.nummenu)
choice = -1;
}
if (bootconf.menuformat != MENUFORMAT_LETTER &&
!isnum(*input) && !usedef)
choice = -1;
return choice;
}
void
doboottypemenu(void)
{
int choice;
char input[80], *ic, *oc;
printf("\n");
/* Display menu */
if (bootconf.menuformat == MENUFORMAT_LETTER) {
for (choice = 0; choice < bootconf.nummenu; choice++)
printf(" %c. %s\n", choice + 'A',
bootconf.desc[choice]);
} else {
/* Can't use %2d format string with libsa */
for (choice = 0; choice < bootconf.nummenu; choice++)
printf(" %s%d. %s\n",
(choice < 9) ? " " : "",
choice + 1,
bootconf.desc[choice]);
}
choice = -1;
for (;;) {
input[0] = '\0';
if (bootconf.timeout < 0) {
if (bootconf.menuformat == MENUFORMAT_LETTER)
printf("\nOption: [%c]:",
bootconf.def + 'A');
else
printf("\nOption: [%d]:",
bootconf.def + 1);
gets(input);
choice = getchoicefrominput(input, bootconf.def);
} else if (bootconf.timeout == 0)
choice = bootconf.def;
else {
printf("\nChoose an option; RETURN for default; "
"SPACE to stop countdown.\n");
if (bootconf.menuformat == MENUFORMAT_LETTER)
printf("Option %c will be chosen in ",
bootconf.def + 'A');
else
printf("Option %d will be chosen in ",
bootconf.def + 1);
input[0] = awaitkey(bootconf.timeout, 1);
input[1] = '\0';
choice = getchoicefrominput(input, bootconf.def);
/* If invalid key pressed, drop to menu */
if (choice == -1)
bootconf.timeout = -1;
}
if (choice < 0)
continue;
if (!strcmp(bootconf.command[choice], "prompt") &&
((boot_params.bp_flags & X86_BP_FLAGS_PASSWORD) == 0 ||
check_password((char *)boot_params.bp_password))) {
printf("type \"?\" or \"help\" for help.\n");
bootmenu(); /* does not return */
} else {
ic = bootconf.command[choice];
/* Split command string at ; into separate commands */
do {
oc = input;
/* Look for ; separator */
for (; *ic && *ic != COMMAND_SEPARATOR; ic++)
*oc++ = *ic;
if (*input == '\0')
continue;
/* Strip out any trailing spaces */
oc--;
for (; *oc == ' ' && oc > input; oc--);
*++oc = '\0';
if (*ic == COMMAND_SEPARATOR)
ic++;
/* Stop silly command strings like ;;; */
if (*input != '\0')
docommand(input);
/* Skip leading spaces */
for (; *ic == ' '; ic++);
} while (*ic);
}
}
}
#endif /* !SMALL */

View file

@ -0,0 +1,53 @@
/* $NetBSD: bootmenu.h,v 1.2 2008/12/13 23:30:54 christos Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _BOOTMENU_H
#define _BOOTMENU_H
#define BOOTCONF "boot.cfg"
#define MAXMENU 20
#define MAXBANNER 12
#define COMMAND_SEPARATOR ';'
void parsebootconf(const char *);
void doboottypemenu(void);
int atoi(const char *);
struct bootconf_def {
char *banner[MAXBANNER]; /* Banner text */
char *command[MAXMENU]; /* Menu commands per entry*/
char *consdev; /* Console device */
int def; /* Default menu option */
char *desc[MAXMENU]; /* Menu text per entry */
int nummenu; /* Number of menu items */
int timeout; /* Timeout in seconds */
int menuformat; /* Print letters instead of numbers? */
int clear; /* Clear the screen? */
} extern bootconf;
#endif /* !_BOOTMENU_H */

View file

@ -0,0 +1,45 @@
/* $NetBSD: bootmod.h,v 1.5 2011/11/28 07:56:54 tls Exp $ */
/*-
* Copyright (c) 2008 Jared D. McNeill <jmcneill@invisible.ca>
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _BOOTMOD_H
#define _BOOTMOD_H
typedef struct boot_module {
char *bm_path;
ssize_t bm_len;
uint8_t bm_type;
#define BM_TYPE_KMOD 0x00
#define BM_TYPE_IMAGE 0x01
#define BM_TYPE_RND 0x02
struct boot_module *bm_next;
} boot_module_t;
extern boot_module_t *boot_modules;
extern bool boot_modules_enabled;
#endif /* !_BOOTMOD_H */

View file

@ -0,0 +1,148 @@
/* $NetBSD: comio.S,v 1.4 2003/04/16 14:23:11 dsl Exp $ */
/* serial console handling
modelled after code in FreeBSD:sys/i386/boot/netboot/start2.S
*/
#include <machine/asm.h>
.text
/**************************************************************************
INIT - Initialization (com number)
**************************************************************************/
ENTRY(cominit)
push %ebp
mov %esp,%ebp
push %ebx
push %edx
push %esi
push %edi
movl 8(%ebp), %edx
call _C_LABEL(prot_to_real) # enter real mode
.code16
# Initialize the serial port (dl) to 9600 baud, 8N1.
movb $0xe3, %al
movb $0, %ah
int $0x14
mov %ax,%bx
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
xor %eax,%eax
mov %bx,%ax
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ebp
ret
/**************************************************************************
PUTC - Print a character (char, com number)
**************************************************************************/
ENTRY(computc)
push %ebp
mov %esp,%ebp
push %ecx
push %ebx
push %edx
push %esi
push %edi
movb 8(%ebp),%cl
movl 12(%ebp),%edx
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb %cl,%al
movb $0x01, %ah
int $0x14
movb %ah,%bl
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
xor %eax,%eax
movb %bl,%al
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ecx
pop %ebp
ret
/**************************************************************************
GETC - Get a character (com number)
**************************************************************************/
ENTRY(comgetc)
push %ebp
mov %esp,%ebp
push %ebx
push %edx
push %esi
push %edi
movl 8(%ebp),%edx
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x02, %ah
int $0x14
mov %ax, %bx
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
xor %eax,%eax
mov %bx,%ax
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ebp
ret
/**************************************************************************
ISKEY - Check for keyboard interrupt (com number)
**************************************************************************/
ENTRY(comstatus)
push %ebp
mov %esp,%ebp
push %ebx
push %edx
push %esi
push %edi
movl 8(%ebp),%edx
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x03, %ah
int $0x14
mov %ax,%bx
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
xor %eax,%eax
mov %bx,%ax
pop %edi
pop %esi
pop %edx
pop %ebx
pop %ebp
ret

View file

@ -0,0 +1,243 @@
/* $NetBSD: comio_direct.c,v 1.10 2008/12/14 18:46:33 christos Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* Charles M. Hannum. All rights reserved.
*
* Taken from sys/dev/isa/com.c and integrated into standalone boot
* programs by Martin Husemann.
*
* 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 Charles M. Hannum.
* 4. The name of the author 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1991 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. 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.
*
* @(#)com.c 7.5 (Berkeley) 5/16/91
*/
#include <sys/types.h>
#include <lib/libsa/stand.h>
#include <machine/pio.h>
#include <dev/ic/comreg.h>
#include "comio_direct.h"
#include "libi386.h"
/* preread buffer for xon/xoff handling */
#define XON 0x11
#define XOFF 0x13
#define SERBUFSIZE 16
static u_char serbuf[SERBUFSIZE];
static int serbuf_read = 0;
static int serbuf_write = 0;
static int stopped = 0;
#define ISSET(t,f) ((t) & (f))
#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
#define RATE_9600 divrnd((COM_FREQ / 16), 9600)
/*
* calculate divisor for a given speed
*/
static int
comspeed(long speed)
{
int x, err;
if (speed <= 0)
speed = 9600;
x = divrnd((COM_FREQ / 16), speed);
if (x <= 0)
return RATE_9600;
err = divrnd((COM_FREQ / 16) * 1000, speed * x) - 1000;
if (err < 0)
err = -err;
if (err > COM_TOLERANCE)
return RATE_9600;
return x;
}
/*
* get a character
*/
int
comgetc_d(int combase)
{
u_char stat, c;
if (serbuf_read != serbuf_write) {
c = serbuf[serbuf_read++];
if (serbuf_read >= SERBUFSIZE)
serbuf_read = 0;
return c;
}
for (;;) {
while (!ISSET(stat = inb(combase + com_lsr), LSR_RXRDY))
continue;
c = inb(combase + com_data);
inb(combase + com_iir);
if (c != XOFF) {
stopped = 0;
break; /* got a real char, deliver it... */
}
stopped = 1;
}
return c;
}
/*
* output a character, return nonzero on success
*/
int
computc_d(int c, int combase)
{
u_char stat;
int timo;
/* check for old XOFF */
while (stopped)
comgetc_d(combase); /* wait for XON */
/* check for new XOFF */
if (comstatus_d(combase)) {
int c = comgetc_d(combase); /* XOFF handled in comgetc_d */
/* stuff char into preread buffer */
serbuf[serbuf_write++] = c;
if (serbuf_write >= SERBUFSIZE)
serbuf_write = 0;
}
/* wait for any pending transmission to finish */
timo = 50000;
while (!ISSET(stat = inb(combase + com_lsr), LSR_TXRDY)
&& --timo)
continue;
if (timo == 0) return 0;
outb(combase + com_data, c);
/* wait for this transmission to complete */
timo = 1500000;
while (!ISSET(stat = inb(combase + com_lsr), LSR_TXRDY)
&& --timo)
continue;
if (timo == 0) return 0;
/* clear any interrupts generated by this transmission */
inb(combase + com_iir);
return 1;
}
/*
* Initialize UART to known state.
*/
int
cominit_d(int combase, int speed)
{
int rate, err;
serbuf_read = 0;
serbuf_write = 0;
outb(combase + com_cfcr, LCR_DLAB);
if (speed == 0) {
/* Try to determine the current baud rate */
rate = inb(combase + com_dlbl) | inb(combase + com_dlbh) << 8;
if (rate == 0)
rate = RATE_9600;
speed = divrnd((COM_FREQ / 16), rate);
err = speed - (speed + 150)/300 * 300;
speed -= err;
if (err < 0)
err = -err;
if (err > 50)
speed = 9600;
}
rate = comspeed(speed);
outb(combase + com_dlbl, rate);
outb(combase + com_dlbh, rate >> 8);
outb(combase + com_cfcr, LCR_8BITS);
outb(combase + com_mcr, MCR_DTR | MCR_RTS);
outb(combase + com_fifo,
FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
outb(combase + com_ier, 0);
return speed;
}
/*
* return nonzero if input char available, do XON/XOFF handling
*/
int
comstatus_d(int combase)
{
/* check if any preread input is already there */
if (serbuf_read != serbuf_write) return 1;
/* check for new stuff on the port */
if (ISSET(inb(combase + com_lsr), LSR_RXRDY)) {
/* this could be XOFF, which we would swallow, so we can't
claim there is input available... */
int c = inb(combase + com_data);
inb(combase + com_iir);
if (c == XOFF) {
stopped = 1;
} else {
/* stuff char into preread buffer */
serbuf[serbuf_write++] = c;
if (serbuf_write >= SERBUFSIZE)
serbuf_write = 0;
return 1;
}
}
return 0; /* nothing out there... */
}

View file

@ -0,0 +1,6 @@
/* $NetBSD: comio_direct.h,v 1.4 2005/11/11 22:25:09 dsl Exp $ */
int cominit_d(int, int);
int computc_d(int, int);
int comgetc_d(int);
int comstatus_d(int);

View file

@ -0,0 +1,126 @@
/* $NetBSD: conio.S,v 1.7 2011/06/16 13:27:59 joerg Exp $ */
/* PC console handling
originally from: FreeBSD:sys/i386/boot/netboot/start2.S
*/
#include <machine/asm.h>
.text
/**************************************************************************
CLR - Clear screen
**************************************************************************/
ENTRY(conclr)
pusha
call _C_LABEL(prot_to_real) # enter real mode
.code16
/* Clear screen. */
movw $0x0600, %ax
movw $0x0700, %bx
xorw %cx, %cx
movw $0x184f, %dx /* 80x25 */
int $0x10
/* Home cursor. */
movb $0x02, %ah
xorw %bx, %bx
xorw %dx, %dx
int $0x10
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
popa
ret
/**************************************************************************
PUTC - Print a character
**************************************************************************/
ENTRY(conputc)
pusha
call _C_LABEL(prot_to_real) # enter real mode
.code16
movw $1,%bx
movb $0x0e,%ah
movb %al, %cl
int $0x10
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
popa
ret
/**************************************************************************
GETC - Get a character
**************************************************************************/
ENTRY(congetc)
xorl %eax, %eax
pusha
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x0,%ah
int $0x16
movb %al,%bl
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movb %bl, 28(%esp)
popa
ret
/**************************************************************************
ISSHIFT - Check for keyboard interrupt; via shift key
**************************************************************************/
ENTRY(conisshift)
xorl %eax, %eax
pusha
call _C_LABEL(prot_to_real) # enter real mode
.code16
xor %bx,%bx
movb $0x2,%ah
int $0x16
testb $3,%al
setnz %bl
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movb %bl, 28(%esp)
popa
ret
/**************************************************************************
ISKEY - Check for keyboard input
**************************************************************************/
ENTRY(coniskey)
xorl %eax, %eax
pusha
call _C_LABEL(prot_to_real) # enter real mode
.code16
xor %bx,%bx
movb $0x1,%ah
int $0x16
setnz %bl
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movb %bl, 28(%esp)
popa
ret

View file

@ -0,0 +1,152 @@
/* $NetBSD: cpufunc.S,v 1.4 2011/06/08 16:03:42 joerg Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
NENTRY(x86_read_psl)
pushfl
popl %eax
ret
NENTRY(x86_write_psl)
movl 4(%esp), %eax
pushl %eax
popfl
ret
NENTRY(x86_disable_intr)
cli
ret
NENTRY(x86_enable_intr)
sti
ret
NENTRY(inb)
movl 4(%esp), %edx
xorl %eax, %eax
inb %dx, %al
ret
NENTRY(insb)
pushl %edi
movl 8(%esp), %edx
movl 12(%esp), %edi
movl 16(%esp), %ecx
cld
rep
insb
popl %edi
ret
NENTRY(inw)
movl 4(%esp), %edx
xorl %eax, %eax
inw %dx, %ax
ret
NENTRY(insw)
pushl %edi
movl 8(%esp), %edx
movl 12(%esp), %edi
movl 16(%esp), %ecx
cld
rep
insw
popl %edi
ret
NENTRY(inl)
movl 4(%esp), %edx
inl %dx, %eax
ret
NENTRY(insl)
pushl %edi
movl 8(%esp), %edx
movl 12(%esp), %edi
movl 16(%esp), %ecx
cld
rep
insl
popl %edi
ret
NENTRY(outb)
movl 4(%esp), %edx
movl 8(%esp), %eax
outb %al, %dx
ret
NENTRY(outsb)
pushl %esi
movl 8(%esp), %edx
movl 12(%esp), %esi
movl 16(%esp), %ecx
cld
rep
outsb
popl %esi
ret
NENTRY(outw)
movl 4(%esp), %edx
movl 8(%esp), %eax
outw %ax, %dx
ret
NENTRY(outsw)
pushl %esi
movl 8(%esp), %edx
movl 12(%esp), %esi
movl 16(%esp), %ecx
cld
rep
outsw
popl %esi
ret
NENTRY(outl)
movl 4(%esp), %edx
movl 8(%esp), %eax
outl %eax, %dx
ret
NENTRY(outsl)
pushl %esi
movl 8(%esp), %edx
movl 12(%esp), %esi
movl 16(%esp), %ecx
cld
rep
outsl
popl %esi
ret

View file

@ -0,0 +1,49 @@
/* $NetBSD: cpufunc.h,v 1.2 2008/04/28 20:23:25 martin Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andrew Doran.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
void x86_disable_intr(void);
void x86_enable_intr(void);
u_long x86_read_psl(void);
void x86_write_psl(u_long);
u_int8_t inb(unsigned);
void insb(unsigned, void *, int);
uint16_t inw(unsigned);
void insw(unsigned, void *, int);
uint32_t inl(unsigned);
void insl(unsigned, void *, int);
void outb(unsigned, uint8_t);
void outsb(unsigned, void *, int);
void outw(unsigned, uint16_t);
void outsw(unsigned, void *, int);
void outl(unsigned, uint32_t);
void outsl(unsigned, void *, int);

View file

@ -0,0 +1,119 @@
/* $NetBSD: doscommain.c,v 1.6 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* argument line processing for DOS .COM programs */
#include <lib/libsa/stand.h>
/* The Program Segment Prefix */
static struct psp{
char mist1[0x2c];
short envseg;
char mist2[0x80-2-0x2c];
char cmdlen;
char cmd[127];
} *PSP = (struct psp*)0;
static char* argv[64]; /* theor max */
static int whitespace(char);
static int
whitespace(char c)
{
if ((c == '\0') || (c == ' ') || (c == '\t')
|| (c == '\r') || (c == '\n'))
return (1);
return 0;
}
enum state {skipping, doing_arg, doing_long_arg};
/* build argv/argc, start real main() */
int doscommain(void);
extern int main(int, char**);
int
doscommain(void)
{
int argc, i;
enum state s;
argv[0] = "???"; /* we don't know */
argc = 1;
s = skipping;
for (i = 0; i < PSP->cmdlen; i++){
if (whitespace(PSP->cmd[i])) {
if (s == doing_arg) {
/* end of argument word */
PSP->cmd[i] = '\0';
s = skipping;
}
continue;
}
if (PSP->cmd[i] == '"') {
/* start or end long arg
* (end only if next char is whitespace)
* XXX but '" ' cannot be in argument
*/
switch (s) {
case skipping:
/* next char begins new argument word */
argv[argc++] = &PSP->cmd[i + 1];
s = doing_long_arg;
break;
case doing_long_arg:
if (whitespace(PSP->cmd[i + 1])) {
PSP->cmd[i] = '\0';
s = skipping;
}
case doing_arg:
/* ignore in the middle of arguments */
default:
break;
}
continue;
}
/* all other characters */
if (s == skipping) {
/* begin new argument word */
argv[argc++] = &PSP->cmd[i];
s = doing_arg;
}
}
if (s != skipping)
PSP->cmd[i] = '\0'; /* to be sure */
/* start real main() */
return main(argc, argv);
}

View file

@ -0,0 +1,620 @@
/* $NetBSD: start_dos.S,v 1.10 2010/12/20 01:12:44 jakllsch Exp $ */
/*
* startup for DOS .COM programs
* with input from:
* netbsd:sys/arch/i386/boot/start.S
* Tor Egge's patches for NetBSD boot (pr port-i386/1002)
* freebsd:sys/i386/boot/netboot/start2.S
* XMS support by Martin Husemann
*/
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* 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.
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <machine/asm.h>
CR0_PE = 0x1
.data
.globl _C_LABEL(ourseg)
_C_LABEL(ourseg):
.long 0
/**************************************************************************
GLOBAL DESCRIPTOR TABLE
**************************************************************************/
#ifdef __ELF__
.align 16
#else
.align 4
#endif
gdt:
.word 0, 0
.byte 0, 0x00, 0x00, 0
#ifdef SUPPORT_LINUX /* additional dummy */
.word 0, 0
.byte 0, 0x00, 0x00, 0
#endif
/* kernel code segment */
.globl flatcodeseg
flatcodeseg = . - gdt
.word 0xffff, 0
.byte 0, 0x9f, 0xcf, 0
/* kernel data segment */
.globl flatdataseg
flatdataseg = . - gdt
.word 0xffff, 0
.byte 0, 0x93, 0xcf, 0
/* boot code segment, base will be patched */
bootcodeseg = . - gdt
.word 0xffff, 0
.byte 0, 0x9e, 0x40, 0
/* boot data segment, base will be patched */
bootdataseg = . - gdt
#ifdef HEAP_BELOW_64K
.word 0xffff, 0
.byte 0, 0x92, 0x00, 0
#else
.word 0xffff, 0
.byte 0, 0x92, 0x4f, 0
#endif
/* 16 bit real mode, base will be patched */
bootrealseg = . - gdt
.word 0xffff, 0
.byte 0, 0x9e, 0x00, 0
/* limits (etc) for data segment in real mode */
bootrealdata = . - gdt
.word 0xffff, 0
.byte 0, 0x92, 0x00, 0
gdtlen = . - gdt
#ifdef __ELF__
.align 16
#else
.align 4
#endif
gdtarg:
.word gdtlen-1 /* limit */
.long 0 /* addr, will be inserted */
.text
ENTRY(start)
.code16
# Check we are in real mode
movl %cr0, %eax
testl $CR0_PE, %eax
jz 2f
mov $1f, %si
call message
ret
1: .asciz "must be in real mode\r\n"
2:
xorl %eax, %eax
mov %cs, %ax
mov %ax, %ds
mov %ax, %es
movl %eax, _C_LABEL(ourseg)
#ifdef STACK_START
add $STACK_START / 16, %ax
mov %ax, %ss
mov $0xfffc, %sp
#endif
/* fix up GDT entries for bootstrap */
#define FIXUP(gdt_index) \
movw %ax, gdt+gdt_index+2; \
movb %bl, gdt+gdt_index+4
mov %cs, %ax
shll $4, %eax
shldl $16, %eax, %ebx
FIXUP(bootcodeseg)
FIXUP(bootrealseg)
FIXUP(bootdataseg)
/* fix up GDT pointer */
addl $gdt, %eax
movl %eax, gdtarg+2
/* change to protected mode */
calll _C_LABEL(real_to_prot)
.code32
/* clear the bss */
movl $_C_LABEL(edata), %edi
movl $_C_LABEL(end), %ecx
subl %edi, %ecx
xorb %al, %al
rep
stosb
call _C_LABEL(doscommain)
ENTRY(_rtt)
call _C_LABEL(prot_to_real)
.code16
ENTRY(exit16)
sti
movb $0x4c, %ah /* return */
int $0x21
/*
* real_to_prot()
* transfer from real mode to protected mode.
*/
ENTRY(real_to_prot)
.code16
pushl %eax
# guarantee that interrupt is disabled when in prot mode
cli
# load the gdtr
lgdtl %cs:gdtarg
# set the PE bit of CR0
movl %cr0, %eax
orl $CR0_PE, %eax
movl %eax, %cr0
# make intrasegment jump to flush the processor pipeline and
# reload CS register
ljmp $bootcodeseg, $xprot
xprot:
.code32
# we are in USE32 mode now
# set up the protected mode segment registers : DS, SS, ES
movl $bootdataseg, %eax
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
#ifdef STACK_START
addl $STACK_START, %esp
#endif
popl %eax
ret
/*
* prot_to_real()
* transfer from protected mode to real mode
*/
ENTRY(prot_to_real)
.code32
pushl %eax
# set up a dummy stack frame for the second seg change.
# Adjust the intersegment jump instruction following
# the clearing of protected mode bit.
# This is self-modifying code, but we need a writable
# code segment, and an intersegment return does not give us that.
movl _C_LABEL(ourseg), %eax
movw %ax, xreal-2
/*
* Load the segment registers while still in protected mode.
* Otherwise the control bits don't get changed.
* The correct values are loaded later.
*/
movw $bootrealdata, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
# Change to use16 mode.
ljmp $bootrealseg, $x16
x16:
.code16
# clear the PE bit of CR0
movl %cr0, %eax
andl $~CR0_PE, %eax
movl %eax, %cr0
# Here we have an 16 bits intersegment jump.
ljmp $0, $xreal /* segment patched above */
xreal:
# we are in real mode now
# set up the real mode segment registers : DS, SS, ES
mov %cs, %ax
mov %ax, %ds
mov %ax, %es
#ifdef STACK_START
add $STACK_START / 16, %ax
mov %ax, %ss
subl $STACK_START, %esp
#else
mov %ax, %ss
#endif
push %bp
movw %sp, %bp
/* check we are returning to an address below 64k */
movw 2/*bp*/ + 4/*eax*/ + 2(%bp), %ax /* high bits ret addr */
test %ax, %ax
jne 1f
pop %bp
sti
popl %eax
retl
1: movw $2f, %si
call message
movl 2/*bp*/ + 4/*eax*/(%bp), %eax /* return address */
call dump_eax
jmp exit16
2: .asciz "prot_to_real can't return to "
/**************************************************************************
___MAIN - Dummy to keep GCC happy
**************************************************************************/
ENTRY(__main)
ret
/*
* pbzero(dst, cnt)
* where dst is a physical address and cnt is the length
*/
ENTRY(pbzero)
.code32
pushl %ebp
movl %esp, %ebp
pushl %es
pushl %edi
cld
# set %es to point at the flat segment
movl $flatdataseg, %eax
mov %ax, %es
movl 8(%ebp), %edi # destination
movl 12(%ebp), %ecx # count
xorl %eax, %eax # value
rep
stosb
popl %edi
popl %es
popl %ebp
ret
/*
* vpbcopy(src, dst, cnt)
* where src is a virtual address and dst is a physical address
*/
ENTRY(vpbcopy)
.code32
pushl %ebp
movl %esp, %ebp
pushl %es
pushl %esi
pushl %edi
cld
# set %es to point at the flat segment
movl $flatdataseg, %eax
mov %ax, %es
movl 8(%ebp), %esi # source
movl 12(%ebp), %edi # destination
movl 16(%ebp), %ecx # count
rep
movsb
popl %edi
popl %esi
popl %es
popl %ebp
ret
/*
* pvbcopy(src, dst, cnt)
* where src is a physical address and dst is a virtual address
*/
ENTRY(pvbcopy)
.code32
pushl %ebp
movl %esp, %ebp
pushl %ds
pushl %esi
pushl %edi
cld
# set %ds to point at the flat segment
movl $flatdataseg, %eax
mov %ax, %ds
movl 8(%ebp), %esi # source
movl 12(%ebp), %edi # destination
movl 16(%ebp), %ecx # count
rep
movsb
popl %edi
popl %esi
popl %ds
popl %ebp
ret
ENTRY(vtophys)
.code32
movl _C_LABEL(ourseg), %eax
shll $4, %eax
addl 4(%esp), %eax
ret
message:
.code16
pushal
message_1:
cld
1: lodsb
testb %al, %al
jz 2f
movb $0xe, %ah
movw $1, %bx
int $0x10
jmp 1b
2: movb $0x86, %ah
mov $16, %cx
int $0x15 /* delay about a second */
popal
ret
/* These are useful for debugging
*/
.data
eax_buf:
.long 0, 0, 0, 0
.text
ENTRY(dump_eax)
.code16
pushal
movw $eax_buf, %si
mov %si, %di
movw $8, %cx
1: roll $4, %eax
mov %ax, %bx
andb $0x0f, %al
addb $0x30, %al /* 30..3f - clear AF */
#if 1 /* 5 bytes to generate real hex... */
daa /* 30..39, 40..45 */
addb $0xc0, %al /* f0..f9, 00..05 */
adcb $0x40, %al /* 30..39, 41..45 */
#endif
movb %al, (%di) /* %es != %ds, so can't ... */
inc %di /* ... use stosb */
mov %bx, %ax
loop 1b
movw $0x20, %ax /* space + null */
movw %ax, (%di)
jmp message_1
.globl _C_LABEL(trace_word)
_C_LABEL(trace_word):
.code32
movl 4(%esp), %edx
call _C_LABEL(prot_to_real)
.code16
movl %edx, %eax
call dump_eax
calll _C_LABEL(real_to_prot)
.code32
ret
.globl _C_LABEL(trace_str)
_C_LABEL(trace_str):
.code32
pushl %esi
call _C_LABEL(prot_to_real)
.code16
mov %sp, %si
mov 8(%si), %si
call message
calll _C_LABEL(real_to_prot)
.code32
popl %esi
ret
#ifdef XMS
/* pointer to XMS driver, 0 if no XMS used */
.data
_C_LABEL(xmsdrv):
.long 0
.text
ENTRY(checkxms)
.code32
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edx
pushl %es
pushl %esi
pushl %edi
call _C_LABEL(prot_to_real) # enter real mode
.code16
movw $0x4300, %ax
int $0x2f /* check if XMS installed */
cmpb $0x80, %al
jnz noxms
movw $0x4310, %ax
int $0x2f /* get driver address */
movw %bx, _C_LABEL(xmsdrv) /* save es:bx to _xmsdrv */
movw %es, _C_LABEL(xmsdrv) + 2
movb $0x08, %ah /* XMS: query free extended memory */
#if 0
movb $0x00, %bl
#endif
lcall *_C_LABEL(xmsdrv)
jmp xdone
noxms: /* no XMS manager found */
mov $0, %dx
xdone:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
xorl %eax, %eax
movw %dx, %ax
popl %edi
popl %esi
popl %es
popl %edx
popl %ebx
popl %ebp
ret
/*
Allocate a block of XMS memory with the requested size
void *xmsalloc(long int kBytes);
Depends on _xmsdrv being set by getextmem() before first call
to this function.
Return value: a physical address.
*/
ENTRY(xmsalloc)
.code32
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edx
pushl %esi
pushl %edi
movl 0x8(%ebp), %edx # Kbytes needed
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x09, %ah # XMS allocate block
lcall *_C_LABEL(xmsdrv) # result: handle in %dx
movb $0x0c, %ah # XMS lock block
lcall *_C_LABEL(xmsdrv) # result: 32 bit physical addr in DX:BX
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl %edx, %eax
shl $16, %eax
movw %bx, %ax # result in %eax
popl %edi
popl %esi
popl %edx
popl %ebx
popl %ebp
ret
/*
* ppbcopy(src, dst, cnt)
* where src and dst are physical addresses
*/
ENTRY(ppbcopy)
.code32
pushl %ebp
movl %esp, %ebp
pushl %es
pushl %esi
pushl %edi
cld
# set %es to point at the flat segment
movl $flatdataseg, %eax
mov %ax, %es
movl 8(%ebp), %esi # source
movl 12(%ebp), %edi # destination
movl 16(%ebp), %ecx # count
es
rep
movsb
popl %edi
popl %esi
popl %es
popl %ebp
ret
#endif

View file

@ -0,0 +1,57 @@
/* $NetBSD: diskbuf.c,v 1.6 2005/12/11 12:17:48 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* data buffer for BIOS disk / DOS I/O */
#include <lib/libsa/stand.h>
#include "diskbuf.h"
char *diskbufp; /* allocated from heap */
const void *diskbuf_user;
/*
* Global shared "diskbuf" is used as read ahead buffer.
* This MAY have to not cross a 64k boundary.
* In practise it is allocated out of the heap early on...
* NB a statically allocated diskbuf is not guaranteed to not
* cross a 64k boundary.
*/
char *
alloc_diskbuf(const void *user)
{
diskbuf_user = user;
if (!diskbufp) {
diskbufp = alloc(DISKBUFSIZE);
if (((int)diskbufp & 0xffff) + DISKBUFSIZE > 0x10000) {
printf("diskbufp %x\n", (unsigned)diskbufp);
panic("diskbuf crosses 64k boundary");
}
}
return diskbufp;
}

View file

@ -0,0 +1,40 @@
/* $NetBSD: diskbuf.h,v 1.4 2005/12/11 12:17:48 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* data buffer for BIOS disk / DOS I/O */
#ifndef DISKBUFSIZE
/* Read ahead buffer large enough for one track on a 1440K floppy.
*/
#define DISKBUFSIZE (18*512)
#endif
extern char *diskbufp; /* allocated from heap... */
extern const void *diskbuf_user; /* using function sets it to unique
value to allow check if overwritten*/
char *alloc_diskbuf(const void *);

View file

@ -0,0 +1,203 @@
/* $NetBSD: dos_file.S,v 1.6 2009/11/21 11:52:57 dsl Exp $ */
/* extracted from Tor Egge's patches for NetBSD boot */
#include <machine/asm.h>
/*
# MSDOS call "INT 0x21 Function 0x3d" to open a file.
# Call with %ah = 0x3d
# %al = 0x0 (access and sharing modes)
# %ds:%dx = ASCIZ filename
# %cl = attribute mask of files to look for
*/
.globl _C_LABEL(doserrno)
_C_LABEL(doserrno): .long 1
ENTRY(dosopen)
.code32
pushl %ebp
movl %esp, %ebp
pushl %edx
pushl %ebx
pushl %esi
pushl %edi
movl 0x8(%ebp), %edx # File name.
call _C_LABEL(prot_to_real) # enter real mode
.code16
push %ds
movl %edx, %eax
shrl $4, %eax
mov %ds, %si
add %si, %ax
mov %ax, %ds
and $0xf, %dx
movb $0x3d, %ah # Open existing file.
movb $0x0 , %al # ro
sti
int $0x21
cli
pop %ds
jnc ok1
mov %ax, _C_LABEL(doserrno)
movl $-1, %edx
jmp err1
ok1:
movl $0,%edx
mov %ax, %dx
err1:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl %edx, %eax # return value in %eax
popl %edi
popl %esi
popl %ebx
popl %edx
popl %ebp
ret
ENTRY(dosread)
.code32
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
movl 0x8(%ebp), %ebx # File handle
movl 0xc(%ebp), %edx # Buffer.
movl 0x10(%ebp), %ecx # Bytes to read
call _C_LABEL(prot_to_real) # enter real mode
.code16
push %ds
movl %edx, %eax
shrl $4, %eax
mov %ds, %si
add %si, %ax
mov %ax, %ds
and $0xf, %dx
movb $0x3f, %ah # Read from file or device
sti
int $0x21
cli
pop %ds
jnc ok2
mov %ax, _C_LABEL(doserrno)
movl $-1, %edx
jmp err2
ok2:
movl $0,%edx
mov %ax, %dx
err2:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl %edx, %eax # return value in %eax
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret
ENTRY(dosclose)
.code32
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
pushl %edi
movl 0x8(%ebp), %ebx # File handle
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x3e, %ah # Close file.
sti
int $0x21
cli
jnc ok3
mov %ax, _C_LABEL(doserrno)
movl $-1, %ebx
jmp err3
ok3:
movl $0, %ebx
err3:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl %ebx, %eax # return value in %eax
popl %edi
popl %esi
popl %ebx
popl %ebp
ret
ENTRY(dosseek)
.code32
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
movl 0x8(%ebp), %ebx # File handle
movl 0xc(%ebp), %ecx # Offset
movl 0x10(%ebp) , %edx # whence
call _C_LABEL(prot_to_real) # enter real mode
.code16
movb $0x42, %ah # Seek
movb %dl, %al # whence
mov %cx, %dx #offs lo
shrl $0x10, %ecx #offs hi
sti
int $0x21
cli
jnc ok4
mov %ax, _C_LABEL(doserrno)
movl $-1, %edx
jmp err4
ok4:
shll $0x10, %edx #new ofs hi
mov %ax, %dx #new ofs lo
err4:
calll _C_LABEL(real_to_prot) # back to protected mode
.code32
movl %edx, %eax # return value in %eax
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret

View file

@ -0,0 +1,240 @@
/* $NetBSD: dosfile.c,v 1.15 2011/06/16 13:27:59 joerg Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* DOS filesystem for libsa
* standalone - uses no device, works only with DOS running
* needs lowlevel parts from dos_file.S
*/
#include <lib/libsa/stand.h>
#include "diskbuf.h"
#include "dosfile.h"
extern int dosopen(const char *);
extern void dosclose(int);
extern int dosread(int, char *, int);
extern int dosseek(int, int, int);
struct dosfile {
int doshandle, off;
};
extern int doserrno; /* in dos_file.S */
static int dos2errno(void);
static int
dos2errno(void)
{
int err;
switch (doserrno) {
case 1:
case 4:
case 12:
default:
err = EIO;
case 2:
case 3:
err = ENOENT;
case 5:
err = EPERM;
case 6:
err = EINVAL;
}
return err;
}
__compactcall int
dos_open(const char *path, struct open_file *f)
{
struct dosfile *df;
df = (struct dosfile *) alloc(sizeof(*df));
if (!df)
return -1;
df->off = 0;
df->doshandle = dosopen(path);
if (df->doshandle < 0) {
#ifdef DEBUG
printf("DOS error %d\n", doserrno);
#endif
dealloc(df, sizeof(*df));
return dos2errno();
}
f->f_fsdata = (void *) df;
return 0;
}
__compactcall int
dos_read(struct open_file *f, void *addr, size_t size, size_t *resid)
{
struct dosfile *df;
int got;
static int tc = 0;
df = (struct dosfile *) f->f_fsdata;
if (!(tc++ % 4))
twiddle();
if ((unsigned long) addr >= 0x10000) {
u_int lsize = size;
while (lsize > 0) {
u_int tsize;
size_t tgot;
char *p = addr;
tsize = lsize;
if (tsize > DISKBUFSIZE)
tsize = DISKBUFSIZE;
alloc_diskbuf(dos_read);
tgot = dosread(df->doshandle, diskbufp, tsize);
if (tgot < 0) {
#ifdef DEBUG
printf("DOS error %d\n", doserrno);
#endif
return dos2errno();
}
memcpy(p, diskbufp, tgot);
p += tgot;
lsize -= tgot;
if (tgot != tsize)
break; /* EOF */
}
got = size - lsize;
} else {
got = dosread(df->doshandle, addr, size);
if (got < 0) {
#ifdef DEBUG
printf("DOS error %d\n", doserrno);
#endif
return dos2errno();
}
}
df->off += got;
size -= got;
if (resid)
*resid = size;
return 0;
}
__compactcall int
dos_close(struct open_file *f)
{
struct dosfile *df;
df = (struct dosfile *) f->f_fsdata;
dosclose(df->doshandle);
if (df)
dealloc(df, sizeof(*df));
return 0;
}
__compactcall int
dos_write(struct open_file *f, void *start, size_t size, size_t *resid)
{
return EROFS;
}
__compactcall int
dos_stat(struct open_file *f, struct stat *sb)
{
struct dosfile *df;
df = (struct dosfile *) f->f_fsdata;
sb->st_mode = 0444;
sb->st_nlink = 1;
sb->st_uid = 0;
sb->st_gid = 0;
sb->st_size = -1;
return 0;
}
__compactcall off_t
dos_seek(struct open_file *f, off_t offset, int where)
{
struct dosfile *df;
int doswhence, res;
#ifdef DOS_CHECK
int checkoffs;
#endif
df = (struct dosfile *) f->f_fsdata;
switch (where) {
case SEEK_SET:
doswhence = 0;
#ifdef DOS_CHECK
checkoffs = offset; /* don't trust DOS */
#endif
break;
case SEEK_CUR:
doswhence = 1;
#ifdef DOS_CHECK
checkoffs = df->off + offset;
#endif
break;
case SEEK_END:
doswhence = 2;
#ifdef DOS_CHECK
checkoffs = -1; /* we dont know len */
#endif
break;
default:
errno = EOFFSET;
return -1;
}
res = dosseek(df->doshandle, offset, doswhence);
if (res == -1) {
errno = dos2errno();
return -1;
}
#ifdef DOS_CHECK
if ((checkoffs != -1) && (res != checkoffs)) {
printf("dosfile: unexpected seek result (%d+%d(%d)=%d)\n",
df->off, offset, where, res);
errno = EOFFSET;
return -1;
}
#endif
df->off = res;
return res;
}

View file

@ -0,0 +1,29 @@
/* $NetBSD: dosfile.h,v 1.4 2005/12/11 12:17:48 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
FS_DEF(dos);

View file

@ -0,0 +1,59 @@
/* $NetBSD: dump_eax.S,v 1.4 2009/11/19 22:08:14 dsl Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
/* This is useful for debugging - although you may need to
* delete some code to fit it in.
* %ds:dump_eax_buff must be somewhere it is safe to write 10 bytes.
*/
ENTRY(dump_eax)
.code16
pusha /* saves bottom 16 bits only! */
movw $dump_eax_buff, %si
mov %si, %di
movw $8, %cx
1: roll $4, %eax
push %ax
andb $0x0f, %al
addb $0x30, %al /* 30..3f - clear AF */
#if 1 /* 5 bytes to generate real hex... */
daa /* 30..39, 40..45 */
addb $0xc0, %al /* f0..f9, 00..05 */
adcb $0x40, %al /* 30..39, 41..46 */
#endif
mov %al,(%di)
inc %di
pop %ax
loop 1b
movw $0x20,(%di) /* space + NIL */
jmp message_1

View file

@ -0,0 +1,743 @@
/* $NetBSD: exec.c,v 1.49 2011/11/28 07:56:54 tls Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 1982, 1986, 1990, 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. 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.
*
* @(#)boot.c 8.1 (Berkeley) 6/10/93
*/
/*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996
* Perry E. Metzger. 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 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.
*
* @(#)boot.c 8.1 (Berkeley) 6/10/93
*/
/*
* starts NetBSD a.out kernel
* needs lowlevel startup from startprog.S
* This is a special version of exec.c to support use of XMS.
*/
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/reboot.h>
#include <machine/multiboot.h>
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include "loadfile.h"
#include "libi386.h"
#include "bootinfo.h"
#include "bootmod.h"
#include "vbe.h"
#ifdef SUPPORT_PS2
#include "biosmca.h"
#endif
#define BOOT_NARGS 6
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
#define MODULE_WARNING_SEC 5
extern struct btinfo_console btinfo_console;
boot_module_t *boot_modules;
bool boot_modules_enabled = true;
bool kernel_loaded;
typedef struct userconf_command {
char *uc_text;
size_t uc_len;
struct userconf_command *uc_next;
} userconf_command_t;
userconf_command_t *userconf_commands = NULL;
static struct btinfo_framebuffer btinfo_framebuffer;
static struct btinfo_modulelist *btinfo_modulelist;
static size_t btinfo_modulelist_size;
static uint32_t image_end;
static char module_base[64] = "/";
static int howto;
static struct btinfo_userconfcommands *btinfo_userconfcommands = NULL;
static size_t btinfo_userconfcommands_size = 0;
static void module_init(const char *);
static void module_add_common(char *, uint8_t);
static void userconf_init(void);
void
framebuffer_configure(struct btinfo_framebuffer *fb)
{
if (fb)
btinfo_framebuffer = *fb;
else {
btinfo_framebuffer.physaddr = 0;
btinfo_framebuffer.flags = 0;
}
}
void
module_add(char *name)
{
return module_add_common(name, BM_TYPE_KMOD);
}
void
splash_add(char *name)
{
return module_add_common(name, BM_TYPE_IMAGE);
}
void
rnd_add(char *name)
{
return module_add_common(name, BM_TYPE_RND);
}
static void
module_add_common(char *name, uint8_t type)
{
boot_module_t *bm, *bmp;
size_t len;
char *str;
while (*name == ' ' || *name == '\t')
++name;
bm = alloc(sizeof(boot_module_t));
len = strlen(name) + 1;
str = alloc(len);
if (bm == NULL || str == NULL) {
printf("couldn't allocate module\n");
return;
}
memcpy(str, name, len);
bm->bm_path = str;
bm->bm_next = NULL;
bm->bm_type = type;
if (boot_modules == NULL)
boot_modules = bm;
else {
for (bmp = boot_modules; bmp->bm_next;
bmp = bmp->bm_next)
;
bmp->bm_next = bm;
}
}
void
userconf_add(char *cmd)
{
userconf_command_t *uc;
size_t len;
char *text;
while (*cmd == ' ' || *cmd == '\t')
++cmd;
uc = alloc(sizeof(*uc));
if (uc == NULL) {
printf("couldn't allocate command\n");
return;
}
len = strlen(cmd) + 1;
text = alloc(len);
if (text == NULL) {
dealloc(uc, sizeof(*uc));
printf("couldn't allocate command\n");
return;
}
memcpy(text, cmd, len);
uc->uc_text = text;
uc->uc_len = len;
uc->uc_next = NULL;
if (userconf_commands == NULL)
userconf_commands = uc;
else {
userconf_command_t *ucp;
for (ucp = userconf_commands; ucp->uc_next != NULL;
ucp = ucp->uc_next)
;
ucp->uc_next = uc;
}
}
static int
common_load_kernel(const char *file, u_long *basemem, u_long *extmem,
physaddr_t loadaddr, int floppy, u_long marks[MARK_MAX])
{
int fd;
#ifdef XMS
u_long xmsmem;
physaddr_t origaddr = loadaddr;
#endif
*extmem = getextmem();
*basemem = getbasemem();
#ifdef XMS
if ((getextmem1() == 0) && (xmsmem = checkxms())) {
u_long kernsize;
/*
* With "CONSERVATIVE_MEMDETECT", extmem is 0 because
* getextmem() is getextmem1(). Without, the "smart"
* methods could fail to report all memory as well.
* xmsmem is a few kB less than the actual size, but
* better than nothing.
*/
if (xmsmem > *extmem)
*extmem = xmsmem;
/*
* Get the size of the kernel
*/
marks[MARK_START] = loadaddr;
if ((fd = loadfile(file, marks, COUNT_KERNEL)) == -1)
return EIO;
close(fd);
kernsize = marks[MARK_END];
kernsize = (kernsize + 1023) / 1024;
loadaddr = xmsalloc(kernsize);
if (!loadaddr)
return ENOMEM;
}
#endif
marks[MARK_START] = loadaddr;
if ((fd = loadfile(file, marks,
LOAD_KERNEL & ~(floppy ? LOAD_BACKWARDS : 0))) == -1)
return EIO;
close(fd);
/* Now we know the root fs type, load modules for it. */
module_add(fsmod);
if (fsmod2 != NULL && strcmp(fsmod, fsmod2) != 0)
module_add(fsmod2);
/*
* Gather some information for the kernel. Do this after the
* "point of no return" to avoid memory leaks.
* (but before DOS might be trashed in the XMS case)
*/
#ifdef PASS_BIOSGEOM
bi_getbiosgeom();
#endif
#ifdef PASS_MEMMAP
bi_getmemmap();
#endif
#ifdef XMS
if (loadaddr != origaddr) {
/*
* We now have done our last DOS IO, so we may
* trash the OS. Copy the data from the temporary
* buffer to its real address.
*/
marks[MARK_START] -= loadaddr;
marks[MARK_END] -= loadaddr;
marks[MARK_SYM] -= loadaddr;
marks[MARK_END] -= loadaddr;
ppbcopy(loadaddr, origaddr, marks[MARK_END]);
}
#endif
marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) &
(-sizeof(int));
image_end = marks[MARK_END];
kernel_loaded = true;
return 0;
}
int
exec_netbsd(const char *file, physaddr_t loadaddr, int boothowto, int floppy,
void (*callback)(void))
{
u_long boot_argv[BOOT_NARGS];
u_long marks[MARK_MAX];
struct btinfo_symtab btinfo_symtab;
u_long extmem;
u_long basemem;
#ifdef DEBUG
printf("exec: file=%s loadaddr=0x%lx\n",
file ? file : "NULL", loadaddr);
#endif
BI_ALLOC(32); /* ??? */
BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console));
howto = boothowto;
if (common_load_kernel(file, &basemem, &extmem, loadaddr, floppy, marks))
goto out;
boot_argv[0] = boothowto;
boot_argv[1] = 0;
boot_argv[2] = vtophys(bootinfo); /* old cyl offset */
boot_argv[3] = marks[MARK_END];
boot_argv[4] = extmem;
boot_argv[5] = basemem;
/* pull in any modules if necessary */
if (boot_modules_enabled) {
module_init(file);
if (btinfo_modulelist) {
BI_ADD(btinfo_modulelist, BTINFO_MODULELIST,
btinfo_modulelist_size);
}
}
userconf_init();
if (btinfo_userconfcommands != NULL)
BI_ADD(btinfo_userconfcommands, BTINFO_USERCONFCOMMANDS,
btinfo_userconfcommands_size);
#ifdef DEBUG
printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
#endif
btinfo_symtab.nsym = marks[MARK_NSYM];
btinfo_symtab.ssym = marks[MARK_SYM];
btinfo_symtab.esym = marks[MARK_END];
BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab));
/* set new video mode if necessary */
vbe_commit();
BI_ADD(&btinfo_framebuffer, BTINFO_FRAMEBUFFER,
sizeof(struct btinfo_framebuffer));
if (callback != NULL)
(*callback)();
startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
x86_trunc_page(basemem*1024));
panic("exec returned");
out:
BI_FREE();
bootinfo = 0;
return -1;
}
static void
extract_device(const char *path, char *buf, size_t buflen)
{
int i;
if (strchr(path, ':') != NULL) {
for (i = 0; i < buflen - 2 && path[i] != ':'; i++)
buf[i] = path[i];
buf[i++] = ':';
buf[i] = '\0';
} else
buf[0] = '\0';
}
static const char *
module_path(boot_module_t *bm, const char *kdev)
{
static char buf[256];
char name_buf[256], dev_buf[64];
const char *name, *name2, *p;
name = bm->bm_path;
for (name2 = name; *name2; ++name2) {
if (*name2 == ' ' || *name2 == '\t') {
strlcpy(name_buf, name, sizeof(name_buf));
if (name2 - name < sizeof(name_buf))
name_buf[name2 - name] = '\0';
name = name_buf;
break;
}
}
if ((p = strchr(name, ':')) != NULL) {
/* device specified, use it */
if (p[1] == '/')
snprintf(buf, sizeof(buf), "%s", name);
else {
p++;
extract_device(name, dev_buf, sizeof(dev_buf));
snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
dev_buf, module_base, p, p);
}
} else {
/* device not specified; load from kernel device if known */
if (name[0] == '/')
snprintf(buf, sizeof(buf), "%s%s", kdev, name);
else
snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
kdev, module_base, name, name);
}
return buf;
}
static int
module_open(boot_module_t *bm, int mode, const char *kdev, bool doload)
{
int fd;
const char *path;
/* check the expanded path first */
path = module_path(bm, kdev);
fd = open(path, mode);
if (fd != -1) {
if ((howto & AB_SILENT) == 0 && doload)
printf("Loading %s ", path);
} else {
/* now attempt the raw path provided */
fd = open(bm->bm_path, mode);
if (fd != -1 && (howto & AB_SILENT) == 0 && doload)
printf("Loading %s ", bm->bm_path);
}
if (!doload && fd == -1) {
printf("WARNING: couldn't open %s", bm->bm_path);
if (strcmp(bm->bm_path, path) != 0)
printf(" (%s)", path);
printf("\n");
}
return fd;
}
static void
module_init(const char *kernel_path)
{
struct bi_modulelist_entry *bi;
struct stat st;
const char *machine;
char kdev[64];
char *buf;
boot_module_t *bm;
size_t len;
off_t off;
int err, fd, nfail = 0;
extract_device(kernel_path, kdev, sizeof(kdev));
switch (netbsd_elf_class) {
case ELFCLASS32:
machine = "i386";
break;
case ELFCLASS64:
machine = "amd64";
break;
default:
machine = "generic";
break;
}
if (netbsd_version / 1000000 % 100 == 99) {
/* -current */
snprintf(module_base, sizeof(module_base),
"/stand/%s/%d.%d.%d/modules", machine,
netbsd_version / 100000000,
netbsd_version / 1000000 % 100,
netbsd_version / 100 % 100);
} else if (netbsd_version != 0) {
/* release */
snprintf(module_base, sizeof(module_base),
"/stand/%s/%d.%d/modules", machine,
netbsd_version / 100000000,
netbsd_version / 1000000 % 100);
}
/* First, see which modules are valid and calculate btinfo size */
len = sizeof(struct btinfo_modulelist);
for (bm = boot_modules; bm; bm = bm->bm_next) {
fd = module_open(bm, 0, kdev, false);
if (fd == -1) {
bm->bm_len = -1;
++nfail;
continue;
}
err = fstat(fd, &st);
if (err == -1 || st.st_size == -1) {
printf("WARNING: couldn't stat %s\n", bm->bm_path);
close(fd);
bm->bm_len = -1;
++nfail;
continue;
}
bm->bm_len = st.st_size;
close(fd);
len += sizeof(struct bi_modulelist_entry);
}
/* Allocate the module list */
btinfo_modulelist = alloc(len);
if (btinfo_modulelist == NULL) {
printf("WARNING: couldn't allocate module list\n");
wait_sec(MODULE_WARNING_SEC);
return;
}
memset(btinfo_modulelist, 0, len);
btinfo_modulelist_size = len;
/* Fill in btinfo structure */
buf = (char *)btinfo_modulelist;
btinfo_modulelist->num = 0;
off = sizeof(struct btinfo_modulelist);
for (bm = boot_modules; bm; bm = bm->bm_next) {
if (bm->bm_len == -1)
continue;
fd = module_open(bm, 0, kdev, true);
if (fd == -1)
continue;
image_end = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
len = pread(fd, (void *)image_end, SSIZE_MAX);
if (len < bm->bm_len) {
if ((howto & AB_SILENT) != 0)
printf("Loading %s ", bm->bm_path);
printf(" FAILED\n");
} else {
btinfo_modulelist->num++;
bi = (struct bi_modulelist_entry *)(buf + off);
off += sizeof(struct bi_modulelist_entry);
strncpy(bi->path, bm->bm_path, sizeof(bi->path) - 1);
bi->base = image_end;
bi->len = len;
switch (bm->bm_type) {
case BM_TYPE_KMOD:
bi->type = BI_MODULE_ELF;
break;
case BM_TYPE_IMAGE:
bi->type = BI_MODULE_IMAGE;
break;
case BM_TYPE_RND:
default:
/* safest -- rnd checks the sha1 */
bi->type = BI_MODULE_RND;
break;
}
if ((howto & AB_SILENT) == 0)
printf(" \n");
}
if (len > 0)
image_end += len;
close(fd);
}
btinfo_modulelist->endpa = image_end;
if (nfail > 0) {
printf("WARNING: %d module%s failed to load\n",
nfail, nfail == 1 ? "" : "s");
#if notyet
wait_sec(MODULE_WARNING_SEC);
#endif
}
}
static void
userconf_init(void)
{
size_t count, len;
userconf_command_t *uc;
char *buf;
off_t off;
/* Calculate the userconf commands list size */
count = 0;
for (uc = userconf_commands; uc != NULL; uc = uc->uc_next)
count++;
len = sizeof(btinfo_userconfcommands) +
count * sizeof(struct bi_userconfcommand);
/* Allocate the userconf commands list */
btinfo_userconfcommands = alloc(len);
if (btinfo_userconfcommands == NULL) {
printf("WARNING: couldn't allocate userconf commands list\n");
return;
}
memset(btinfo_userconfcommands, 0, len);
btinfo_userconfcommands_size = len;
/* Fill in btinfo structure */
buf = (char *)btinfo_userconfcommands;
off = sizeof(*btinfo_userconfcommands);
btinfo_userconfcommands->num = 0;
for (uc = userconf_commands; uc != NULL; uc = uc->uc_next) {
struct bi_userconfcommand *bi;
bi = (struct bi_userconfcommand *)(buf + off);
strncpy(bi->text, uc->uc_text, sizeof(bi->text) - 1);
off += sizeof(*bi);
btinfo_userconfcommands->num++;
}
}
int
exec_multiboot(const char *file, char *args)
{
struct multiboot_info *mbi;
struct multiboot_module *mbm;
struct bi_modulelist_entry *bim;
int i, len;
u_long marks[MARK_MAX];
u_long extmem;
u_long basemem;
char *cmdline;
mbi = alloc(sizeof(struct multiboot_info));
mbi->mi_flags = MULTIBOOT_INFO_HAS_MEMORY;
if (common_load_kernel(file, &basemem, &extmem, 0, 0, marks))
goto out;
mbi->mi_mem_upper = extmem;
mbi->mi_mem_lower = basemem;
if (args) {
mbi->mi_flags |= MULTIBOOT_INFO_HAS_CMDLINE;
len = strlen(file) + 1 + strlen(args) + 1;
cmdline = alloc(len);
snprintf(cmdline, len, "%s %s", file, args);
mbi->mi_cmdline = (char *) vtophys(cmdline);
}
/* pull in any modules if necessary */
if (boot_modules_enabled) {
module_init(file);
if (btinfo_modulelist) {
mbm = alloc(sizeof(struct multiboot_module) *
btinfo_modulelist->num);
bim = (struct bi_modulelist_entry *)
(((char *) btinfo_modulelist) +
sizeof(struct btinfo_modulelist));
for (i = 0; i < btinfo_modulelist->num; i++) {
mbm[i].mmo_start = bim->base;
mbm[i].mmo_end = bim->base + bim->len;
mbm[i].mmo_string = (char *)vtophys(bim->path);
mbm[i].mmo_reserved = 0;
bim++;
}
mbi->mi_flags |= MULTIBOOT_INFO_HAS_MODS;
mbi->mi_mods_count = btinfo_modulelist->num;
mbi->mi_mods_addr = vtophys(mbm);
}
}
#ifdef DEBUG
printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
#endif
#if 0
if (btinfo_symtab.nsym) {
mbi->mi_flags |= MULTIBOOT_INFO_HAS_ELF_SYMS;
mbi->mi_elfshdr_addr = marks[MARK_SYM];
btinfo_symtab.nsym = marks[MARK_NSYM];
btinfo_symtab.ssym = marks[MARK_SYM];
btinfo_symtab.esym = marks[MARK_END];
#endif
multiboot(marks[MARK_ENTRY], vtophys(mbi),
x86_trunc_page(mbi->mi_mem_lower*1024));
panic("exec returned");
out:
dealloc(mbi, 0);
return -1;
}
void
x86_progress(const char *fmt, ...)
{
va_list ap;
if ((howto & AB_SILENT) != 0)
return;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}

View file

@ -0,0 +1,80 @@
/* $NetBSD: gatea20.c,v 1.12 2009/08/23 12:31:05 jmcneill Exp $ */
/* extracted from freebsd:sys/i386/boot/biosboot/io.c */
#include <sys/types.h>
#include <lib/libsa/stand.h>
#include "libi386.h"
#include "biosmca.h"
#include "cpufunc.h"
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
#define K_STATUS 0x64 /* keyboard status */
#define K_CMD 0x64 /* keybd ctlr command (write-only) */
#define K_OBUF_FUL 0x01 /* output buffer full */
#define K_IBUF_FUL 0x02 /* input buffer full */
#define KC_CMD_WIN 0xd0 /* read output port */
#define KC_CMD_WOUT 0xd1 /* write output port */
#define KB_A20 0x9f /* enable A20,
reset (!),
enable output buffer full interrupt
enable data line
disable clock line */
/*
* Gate A20 for high memory
*/
static unsigned char x_20 = KB_A20;
void
gateA20(void)
{
int biosA20(void);
u_long psl;
/*
* First, try asking the BIOS to enable A20.
*
* If that fails, try system configuration port 0x92 but only
* if known to be necessary. Not all systems enable A20 via the
* keyboard controller, some don't have keyboard controllers,
* and playing with port 0x92 may cause some systems to break.
*
* Otherwise, use the traditional method (keyboard controller).
*/
if (!biosA20())
return;
psl = x86_read_psl();
x86_disable_intr();
if (
#ifdef SUPPORT_PS2
biosmca_ps2model == 0xf82 ||
#endif
(inb(K_STATUS) == 0xff && inb(K_RDWR) == 0xff)) {
int data;
data = inb(0x92);
outb(0x92, data | 0x2);
} else {
while (inb(K_STATUS) & K_IBUF_FUL);
while (inb(K_STATUS) & K_OBUF_FUL)
(void)inb(K_RDWR);
outb(K_CMD, KC_CMD_WOUT);
while (inb(K_STATUS) & K_IBUF_FUL);
outb(K_RDWR, x_20);
while (inb(K_STATUS) & K_IBUF_FUL);
while (inb(K_STATUS) & K_OBUF_FUL)
(void)inb(K_RDWR);
}
x86_write_psl(psl);
}

View file

@ -0,0 +1,93 @@
/* $NetBSD: getextmemx.c,v 1.10 2011/06/16 13:27:59 joerg Exp $ */
/*
* Copyright (c) 1997, 1999
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Try 2 more fancy BIOS calls to get the size of extended
* memory besides the classical int15/88, take maximum.
* needs lowlevel parts from biosmemx.S and biosmem.S
*/
#include <lib/libsa/stand.h>
#include "libi386.h"
int
getextmemx(void)
{
int buf[5], i;
int extmem = getextmem1();
#ifdef SUPPORT_PS2
struct {
uint16_t len;
uint32_t dta[8];
/* pad to 64 bytes - without this, machine would reset */
uint8_t __pad[30];
} __packed bufps2;
#endif
#ifdef DEBUG_MEMSIZE
printf("extmem1: %xk\n", extmem);
#endif
if (!getextmem2(buf)) {
#ifdef DEBUG_MEMSIZE
printf("extmem2: %xk + %xk\n", buf[0], buf[1] * 64);
#endif
if (buf[0] <= 15 * 1024) {
int help = buf[0];
if (help == 15 * 1024)
help += buf[1] * 64;
if (extmem < help)
extmem = help;
}
}
i = 0;
do {
if (getmementry(&i, buf))
break;
#ifdef DEBUG_MEMSIZE
printf("mementry: (%d) %x %x %x %x %x\n",
i, buf[0], buf[1], buf[2], buf[3], buf[4]);
#endif
if ((buf[4] == 1 && buf[0] == 0x100000)
&& extmem < buf[2] / 1024)
extmem = buf[2] / 1024;
} while (i);
#ifdef SUPPORT_PS2
/* use local memory information from RETURN MEMORY-MAP INFORMATION */
if (!getextmemps2((void *) &bufps2)) {
int help = bufps2.dta[0];
if (help == 15 * 1024)
help += bufps2.dta[1];
if (extmem < help)
extmem = help;
}
#endif
return extmem;
}

View file

@ -0,0 +1,41 @@
/* $NetBSD: getsecs.c,v 1.4 2009/01/12 11:32:44 tsutsui Exp $ */
/* extracted from netbsd:sys/arch/i386/netboot/misc.c */
#include <sys/types.h>
#include <lib/libsa/stand.h>
#include <lib/libsa/net.h>
#include "libi386.h"
static inline u_long bcd2dec(u_long);
static inline u_long
bcd2dec(u_long arg)
{
return (arg >> 4) * 10 + (arg & 0x0f);
}
satime_t
getsecs(void) {
/*
* Return the current time in seconds
*/
u_long t;
satime_t sec;
if (biosgetrtc(&t))
panic("RTC invalid");
sec = bcd2dec(t & 0xff);
sec *= 60;
t >>= 8;
sec += bcd2dec(t & 0xff);
sec *= 60;
t >>= 8;
sec += bcd2dec(t & 0xff);
return sec;
}

View file

@ -0,0 +1,43 @@
/* $NetBSD: isadma.c,v 1.2 2008/12/14 17:03:43 christos Exp $ */
/* from: NetBSD:dev/isa/isadma.c */
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include "isadmavar.h"
#define IO_DMA1 0x000 /* 8237A DMA Controller #1 */
#define IO_DMA2 0x0C0 /* 8237A DMA Controller #2 */
#define DMA37MD_CASCADE 0xc0 /* cascade mode */
#define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */
#define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */
#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */
#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
/*
* isa_dmacascade(): program 8237 DMA controller channel to accept
* external dma control by a board.
*/
void
isa_dmacascade(int chan)
{
#ifdef ISADMA_DEBUG
if (chan < 0 || chan > 7)
panic("isa_dmacascade: impossible request");
#endif
/* set dma channel mode, and set dma channel mode */
if ((chan & 4) == 0) {
outb(DMA1_MODE, chan | DMA37MD_CASCADE);
outb(DMA1_SMSK, chan);
} else {
chan &= 3;
outb(DMA2_MODE, chan | DMA37MD_CASCADE);
outb(DMA2_SMSK, chan);
}
}

View file

@ -0,0 +1,3 @@
/* $NetBSD: isadmavar.h,v 1.2 2008/12/14 17:03:43 christos Exp $ */
void isa_dmacascade(int);

View file

@ -0,0 +1,231 @@
/* $NetBSD: isapnp.c,v 1.5 2008/12/14 17:03:43 christos Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* minimal ISA PnP implementation: find adapter, return settings (1 IO and 1
* DMA only for now)
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include "isapnpvar.h"
#define PNPADDR 0x0279
#define PNPWDATA 0x0a79
#define PNPRDATAMIN 0x0203
#define PNPRDATAMAX 0x03ff
enum {
DATAPORT,
ISOL,
CONTROL,
WAKE,
RESDATA,
RESSTAT,
SETCSN,
SETLDEV
};
#define MEMBASE 0x40
#define IOBASE 0x60
#define INTBASE 0x70
#define DMABASE 0x74
static int pnpdataport;
static int
getiobase(int nr)
{
unsigned short iobase;
outb(PNPADDR, SETLDEV);
outb(PNPWDATA, 0); /* subdev 0 */
outb(PNPADDR, IOBASE + nr * 2);
iobase = (inb(pnpdataport) << 8);
outb(PNPADDR, IOBASE + nr * 2 + 1);
iobase |= inb(pnpdataport);
return iobase;
}
static int
getdmachan(int nr)
{
unsigned char dmachannel;
outb(PNPADDR, SETLDEV);
outb(PNPWDATA, 0); /* subdev 0 */
outb(PNPADDR, DMABASE + nr);
dmachannel = inb(pnpdataport) & 0x07;
return dmachannel;
}
struct cardid {
unsigned char eisaid[4];
unsigned int serial;
unsigned char crc;
};
/*
do isolation, call pnpscanresc() in board config state
*/
static int
pnpisol(int csn)
{
unsigned char buf[9];
int i, j;
struct cardid *id;
unsigned char crc = 0x6a;
/*
* do 72 pairs of reads from ISOL register all but 1 go to sleep
* state (ch. 3.3)
*/
outb(PNPADDR, ISOL);
delay(1000);
for (i = 0; i < 9; i++) {
for (j = 0; j < 8; j++) {
unsigned char a, b;
int bitset;
a = inb(pnpdataport);
b = inb(pnpdataport);
if ((a == 0x55) && (b == 0xaa))
bitset = 1;
else if ((a == 0xff) && (b == 0xff))
bitset = 0;
else
return -1; /* data port conflict */
buf[i] = (buf[i] >> 1) | (bitset << 7);
if (i < 8) /* calc crc for first 8 bytes (app.
* B.2) */
crc = (crc >> 1) |
((bitset != ((crc & 1) == !(crc & 2))) << 7);
delay(250);
}
}
id = (struct cardid *) buf;
if (id->crc != crc)
return 0; /* normal end */
outb(PNPADDR, SETCSN);
outb(PNPWDATA, csn); /* set csn for winning card and put it to
* config state */
return (id->eisaid[0] << 24) | (id->eisaid[1] << 16)
| (id->eisaid[2] << 8) | (id->eisaid[3]);
}
static void
pnpisolreset(void)
{
outb(PNPADDR, WAKE);
outb(PNPWDATA, 0); /* put all remaining cards to isolation state */
}
/*
send initiation sequence (app. B.1)
*/
static void
pnpinit(void)
{
int i;
unsigned char key = 0x6a;
outb(PNPADDR, 0);
outb(PNPADDR, 0);
for (i = 0; i < 32; i++) {
outb(PNPADDR, key);
key = (key >> 1) |
(((key & 1) == !(key & 2)) << 7);
}
}
int
isapnp_finddev(int id, int *iobase, int *dmachan)
{
int csn;
outb(PNPADDR, CONTROL);
outb(PNPWDATA, 2); /* XXX force wait for key */
/* scan all allowed data ports (ch. 3.1) */
for (pnpdataport = PNPRDATAMIN; pnpdataport <= PNPRDATAMAX;
pnpdataport += 4) {
int res, found = 0;
pnpinit(); /* initiation sequence */
outb(PNPADDR, CONTROL);
outb(PNPWDATA, 4); /* CSN=0 - only these respond to
* WAKE[0] */
outb(PNPADDR, WAKE);
outb(PNPWDATA, 0); /* put into isolation state */
outb(PNPADDR, DATAPORT);
outb(PNPWDATA, pnpdataport >> 2); /* set READ_DATA port */
csn = 0;
do {
res = pnpisol(++csn);
if ((res) == id) {
if (iobase)
*iobase = getiobase(0);
if (dmachan)
*dmachan = getdmachan(0);
found = 1;
}
pnpisolreset();
} while ((res != 0) && (res != -1));
outb(PNPADDR, CONTROL);
outb(PNPWDATA, 2); /* return to wait for key */
if (csn > 1) /* at least 1 board found */
return !found;
/* if no board found, try next dataport */
}
return -1; /* nothing found */
}

View file

@ -0,0 +1,29 @@
/* $NetBSD: isapnpvar.h,v 1.4 2008/12/14 17:03:43 christos Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
int isapnp_finddev(int, int*, int*);

View file

@ -0,0 +1,145 @@
/* $NetBSD: libi386.h,v 1.38 2011/11/28 07:56:54 tls Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
typedef unsigned long physaddr_t;
/* this is in startup code */
void vpbcopy(const void *, void *, size_t);
void pvbcopy(const void *, void *, size_t);
void pbzero(void *, size_t);
physaddr_t vtophys(void *);
ssize_t pread(int, void *, size_t);
void startprog(physaddr_t, int, unsigned long *, physaddr_t);
void multiboot(physaddr_t, physaddr_t, physaddr_t);
int exec_netbsd(const char *, physaddr_t, int, int, void (*)(void));
int exec_multiboot(const char *, char *);
void delay(int);
int getbasemem(void);
int getextmemx(void);
int getextmem1(void);
int biosvideomode(void);
#ifdef CONSERVATIVE_MEMDETECT
#define getextmem() getextmem1()
#else
#define getextmem() getextmemx()
#endif
void printmemlist(void);
void reboot(void);
void gateA20(void);
void clear_pc_screen(void);
void initio(int);
#define CONSDEV_PC 0
#define CONSDEV_COM0 1
#define CONSDEV_COM1 2
#define CONSDEV_COM2 3
#define CONSDEV_COM3 4
#define CONSDEV_COM0KBD 5
#define CONSDEV_COM1KBD 6
#define CONSDEV_COM2KBD 7
#define CONSDEV_COM3KBD 8
#define CONSDEV_AUTO (-1)
int iskey(int);
char awaitkey(int, int);
void wait_sec(int);
/* this is in "user code"! */
int parsebootfile(const char *, char **, char **, int *, int *, const char **);
#ifdef XMS
physaddr_t ppbcopy(physaddr_t, physaddr_t, int);
int checkxms(void);
physaddr_t xmsalloc(int);
#endif
/* parseutils.c */
char *gettrailer(char *);
int parseopts(const char *, int *);
int parseboot(char *, char **, int *);
/* menuutils.c */
struct bootblk_command {
const char *c_name;
void (*c_fn)(char *);
};
void bootmenu(void);
void docommand(char *);
/* in "user code": */
void command_help(char *);
extern const struct bootblk_command commands[];
/* asm bios/dos calls */
__compactcall int biosdisk_extread(int, void *);
int biosdisk_read(int, int, int, int, int, void *);
__compactcall int biosdisk_reset(int);
__compactcall int biosgetrtc(u_long *);
int biosgetsystime(void);
int comgetc(int);
void cominit(int);
__compactcall int computc(int, int);
int comstatus(int);
int congetc(void);
int conisshift(void);
int coniskey(void);
__compactcall void conputc(int);
void conclr(void);
int getextmem2(int *);
__compactcall int getextmemps2(void *);
int getmementry(int *, int *);
__compactcall int biosdisk_int13ext(int);
__compactcall int biosdisk_getinfo(int);
struct biosdisk_extinfo;
__compactcall int biosdisk_getextinfo(int, struct biosdisk_extinfo *);
int get_harddrives(void);
void biosdisk_probe(void);
int pcibios_cfgread(unsigned int, int, int *);
int pcibios_cfgwrite(unsigned int, int, int);
int pcibios_finddev(int, int, int, unsigned int *);
int pcibios_present(int *);
void dosclose(int);
int dosopen(char *);
int dosread(int, char *, int);
int dosseek(int, int, int);
extern int doserrno; /* in dos_file.S */
void module_add(char *);
void splash_add(char *);
void rnd_add(char *);
void userconf_add(char *);
struct btinfo_framebuffer;
void framebuffer_configure(struct btinfo_framebuffer *);

View file

@ -0,0 +1,84 @@
/* $NetBSD: menuutils.c,v 1.3 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1996, 1997
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996, 1997
* Perry E. Metzger. All rights reserved.
* Copyright (c) 1997
* Jason R. Thorpe. 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 acknowledgements:
* This product includes software developed for the NetBSD Project
* by Matthias Drochner.
* This product includes software developed for the NetBSD Project
* by Perry E. Metzger.
* 4. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <lib/libkern/libkern.h>
#include <lib/libsa/stand.h>
#include "libi386.h"
void
docommand(char *arg)
{
char *options;
int i;
options = gettrailer(arg);
for (i = 0; commands[i].c_name != NULL; i++) {
if (strcmp(arg, commands[i].c_name) == 0) {
(*commands[i].c_fn)(options);
return;
}
}
printf("unknown command\n");
command_help(NULL);
}
void
bootmenu(void)
{
char input[80];
for (;;) {
char *c = input;
input[0] = '\0';
printf("> ");
gets(input);
/*
* Skip leading whitespace.
*/
while (*c == ' ')
c++;
if (*c)
docommand(c);
}
}

View file

@ -0,0 +1,79 @@
/* $NetBSD: message.S,v 1.4 2009/11/19 22:10:03 dsl Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
.global message, message_1
#if defined(BOOT_MSG_COM0) && !defined(COM_PORT_VAL)
#define COM_PORT_VAL $0x3f8 /* Value for COM1 */
#endif
/*
* message: write the error message in %ds:%esi to the console
*/
message:
/*
* BIOS call "INT 10H Function 0Eh" to write character to console
* Call with %ah = 0x0e
* %al = character
* %bh = page
* %bl = foreground color
*/
.code16
pusha
message_1: /* for dump_eax */
lodsb
1:
#ifdef COM_PORT_VAL
mov COM_PORT_VAL, %dx
outb %al, %dx
add $5, %dl
2: inb %dx
test $0x40, %al
jz 2b
#else
movb $0x0e, %ah
movw $0x0001, %bx
int $0x10
#endif
lodsb
testb %al, %al
jnz 1b
#ifdef MESSAGE_PAUSE
/* Delay for about 1 second to allow message to be read */
movb $0x86, %ah
mov $16, %cx /* about a second */
int $0x15 /* delay cx:dx usecs */
#endif
popa
ret

View file

@ -0,0 +1,87 @@
/* $NetBSD: message32.S,v 1.1 2009/11/19 22:13:17 dsl Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <machine/asm.h>
/*
* Output messages directly to serial port from 32bit mode.
* Useful for debugging when the real-prot is suspect.
*
* %ds:dump_eax_buff must be somewhere it is safe to write 12 bytes.
*/
#ifndef COM_PORT_VAL
#define COM_PORT_VAL $0x3f8 /* Standard address COM1 (dty0) */
#endif
.globl message32
.code32
message32:
pusha
message32_1:
lodsb
2:
mov COM_PORT_VAL, %dx
outb %al, %dx
add $5, %dl
3: inb %dx
test $0x40, %al
jz 3b
lodsb
test %al, %al
jnz 2b
popa
ret
.globl dump_eax32
dump_eax32:
pusha
movl $dump_eax_buff, %esi
mov %esi, %edi
push $8
pop %ecx
1: roll $4, %eax
push %eax
andb $0x0f, %al
addb $0x30, %al /* 30..3f - clear AF */
#if 1 /* 5 bytes to generate real hex... */
daa /* 30..39, 40..45 */
addb $0xc0, %al /* f0..f9, 00..05 */
adcb $0x40, %al /* 30..39, 41..46 */
#endif
movb %al,(%edi)
inc %edi
pop %eax
loop 1b
push $0x20 /* space + 3 NULs */
pop (%edi)
jmp message32_1

View file

@ -0,0 +1,124 @@
/* $NetBSD: multiboot.S,v 1.1 2008/10/11 11:06:20 joerg Exp $ */
/* starts program in protected mode / flat space
with given stackframe
needs global variables flatcodeseg and flatdataseg
(gdt offsets)
derived from: NetBSD:sys/arch/i386/stand/lib/startprog.S
*/
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* 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.
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <machine/asm.h>
#define MULTIBOOT_INFO_MAGIC 0x2BADB002
/*
* multiboot(phyaddr,header,stack)
* start the program on protected mode where phyaddr is the entry point
*/
ENTRY(multiboot)
pushl %ebp
movl %esp, %ebp
# prepare a new stack
movl $flatdataseg, %eax
movw %ax, %es # for arg copy
movl 16(%ebp), %ebx # stack
subl $4,%ebx
movl %ebx, %edi
movl 12(%ebp), %ebx # header
movl 8(%ebp), %ecx # entry
# set new stackptr (movsl decd sp 1 more -> dummy return address)
movw %ax, %ss
movl %edi, %esp
# push on our entry address
movl $flatcodeseg, %eax # segment
pushl %eax
pushl %ecx #entry
# convert over the other data segs
movl $flatdataseg, %eax
mov %ax, %ds
mov %ax, %es
movl $MULTIBOOT_INFO_MAGIC, %eax
# convert the PC (and code seg)
lret

View file

@ -0,0 +1,227 @@
/* $NetBSD: 3c509.c,v 1.10 2008/12/14 18:46:33 christos Exp $ */
/* stripped down from freebsd:sys/i386/netboot/3c509.c */
/**************************************************************************
NETBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters.
Date: Mar 22 1995
This code is based heavily on David Greenman's if_ed.c driver and
Andres Vega Garcia's if_ep.c driver.
Copyright (C) 1993-1994, David Greenman, Martin Renters.
Copyright (C) 1993-1995, Andres Vega Garcia.
Copyright (C) 1995, Serge Babkin.
This software may be used, modified, copied, distributed, and sold, in
both source and binary form provided that the above copyright and these
terms are retained. Under no circumstances are the authors responsible for
the proper functioning of this software, nor do the authors assume any
responsibility for damages incurred with its use.
3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
3c509.c,v 1.2 1995/05/30 07:58:52 rgrimes Exp
***************************************************************************/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <libi386.h>
#ifdef _STANDALONE
#include <bootinfo.h>
#endif
#include "etherdrv.h"
#include "3c509.h"
unsigned ether_medium;
unsigned short eth_base;
extern void epreset(void);
extern int ep_get_e(int);
static int send_ID_sequence(int);
static int get_eeprom_data(int, int);
u_char eth_myaddr[6];
static struct mtabentry {
int address_cfg; /* configured connector */
int config_bit; /* connector present */
char *name;
} mediatab[] = { /* indexed by media type - etherdrv.h */
{3, IS_BNC, "BNC"},
{0, IS_UTP, "UTP"},
{1, IS_AUI, "AUI"},
};
#ifdef _STANDALONE
static struct btinfo_netif bi_netif;
#endif
#ifndef _STANDALONE
extern int mapio(void);
#endif
/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
int
EtherInit(unsigned char *myadr)
{
/* common variables */
int i;
/* variables for 3C509 */
int data, j, id_port = EP_ID_PORT;
u_short k;
/* int ep_current_tag = EP_LAST_TAG + 1; */
u_short *p;
struct mtabentry *m;
#ifndef _STANDALONE
if (mapio()) {
printf("no IO access\n");
return 0;
}
#endif
/*********************************************************
Search for 3Com 509 card
***********************************************************/
/*
ep_current_tag--;
*/
/* Look for the ISA boards. Init and leave them actived */
/* search for the first card, ignore all others */
outb(id_port, 0xc0); /* Global reset */
delay(1000);
/*
for (i = 0; i < EP_MAX_BOARDS; i++) {
*/
outb(id_port, 0);
outb(id_port, 0);
send_ID_sequence(id_port);
data = get_eeprom_data(id_port, EEPROM_MFG_ID);
if (data != MFG_ID)
return 0;
/* resolve contention using the Ethernet address */
for (j = 0; j < 3; j++)
data = get_eeprom_data(id_port, j);
eth_base =
(get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
outb(id_port, EP_LAST_TAG); /* tags board */
outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG);
/*
ep_current_tag--;
break;
}
if (i == EP_MAX_BOARDS)
return 0;
*/
/*
* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
* 0x9[0-f]50
*/
GO_WINDOW(0);
k = (u_int)ep_get_e(EEPROM_PROD_ID);
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
return 0;
printf("3C5x9 board on ISA at 0x%x - ", eth_base);
/* test for presence of connectors */
i = inw(IS_BASE + EP_W0_CONFIG_CTRL);
j = inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14;
for (ether_medium = 0, m = mediatab;
ether_medium < sizeof(mediatab) / sizeof(mediatab[0]);
ether_medium++, m++) {
if (j == m->address_cfg) {
if (!(i & m->config_bit)) {
printf("%s not present\n", m->name);
return 0;
}
printf("using %s\n", m->name);
goto ok;
}
}
printf("unknown connector\n");
return 0;
ok:
/*
* Read the station address from the eeprom
*/
p = (u_short *) eth_myaddr;
for (i = 0; i < 3; i++) {
u_short help;
GO_WINDOW(0);
help = ep_get_e(i);
p[i] = ((help & 0xff) << 8) | ((help & 0xff00) >> 8);
GO_WINDOW(2);
outw(BASE + EP_W2_ADDR_0 + (i * 2), help);
}
for (i = 0; i < 6; i++)
myadr[i] = eth_myaddr[i];
epreset();
#ifdef _STANDALONE
strncpy(bi_netif.ifname, "ep", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_ISA;
bi_netif.addr.iobase = eth_base;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
#endif
return 1;
}
static int
send_ID_sequence(int port)
{
int cx, al;
for (al = 0xff, cx = 0; cx < 255; cx++) {
outb(port, al);
al <<= 1;
if (al & 0x100)
al ^= 0xcf;
}
return 1;
}
/*
* We get eeprom data from the id_port given an offset into the eeprom.
* Basically; after the ID_sequence is sent to all of the cards; they enter
* the ID_CMD state where they will accept command requests. 0x80-0xbf loads
* the eeprom data. We then read the port 16 times and with every read; the
* cards check for contention (ie: if one card writes a 0 bit and another
* writes a 1 bit then the host sees a 0. At the end of the cycle; each card
* compares the data on the bus; if there is a difference then that card goes
* into ID_WAIT state again). In the meantime; one bit of data is returned in
* the AX register which is conveniently returned to us by inb(). Hence; we
* read 16 times getting one bit of data with each read.
*/
static int
get_eeprom_data(int id_port, int offset)
{
int i, data = 0;
outb(id_port, 0x80 + offset);
delay(1000);
for (i = 0; i < 16; i++)
data = (data << 1) | (inw(id_port) & 1);
return data;
}

View file

@ -0,0 +1,393 @@
/* $NetBSD: 3c509.h,v 1.6 2006/11/24 22:52:16 wiz Exp $ */
/*
* Copyright (c) 1993 Herb Peyerl
* 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. The name of the author 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* if_epreg.h,v 1.4 1994/11/13 10:12:37 gibbs Exp Modified by:
*
October 2, 1994
Modified by: Andres Vega Garcia
INRIA - Sophia Antipolis, France
e-mail: avega@sophia.inria.fr
finger: avega@pax.inria.fr
*/
/*
* Ethernet software status per interface.
*/
/*
* Some global constants
*/
#define ETHER_MIN_LEN 64
#define ETHER_MAX_LEN 1518
#define ETHER_ADDR_LEN 6
#define TX_INIT_RATE 16
#define TX_INIT_MAX_RATE 64
#define RX_INIT_LATENCY 64
#define RX_INIT_EARLY_THRESH 64
#define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */
#define MIN_RX_EARLY_THRESHL 4
#define EEPROMSIZE 0x40
#define MAX_EEPROMBUSY 1000
#define EP_LAST_TAG 0xd7
#define EP_MAX_BOARDS 16
#define EP_ID_PORT 0x100
/*
* some macros to acces long named fields
*/
#define IS_BASE (eth_base)
#define BASE (eth_base)
/*
* Commands to read/write EEPROM through EEPROM command register (Window 0,
* Offset 0xa)
*/
#define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */
#define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */
#define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */
#define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */
#define EEPROM_BUSY (1<<15)
#define EEPROM_TST_MODE (1<<14)
/*
* Some short functions, worth to let them be a macro
*/
#define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
#define GO_WINDOW(x) outw(BASE+EP_COMMAND, WINDOW_SELECT|(x))
/**************************************************************************
* *
* These define the EEPROM data structure. They are used in the probe
* function to verify the existence of the adapter after having sent
* the ID_Sequence.
*
* There are others but only the ones we use are defined here.
*
**************************************************************************/
#define EEPROM_NODE_ADDR_0 0x0 /* Word */
#define EEPROM_NODE_ADDR_1 0x1 /* Word */
#define EEPROM_NODE_ADDR_2 0x2 /* Word */
#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
#define EEPROM_ADDR_CFG 0x8 /* Base addr */
#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
/**************************************************************************
* *
* These are the registers for the 3Com 3c509 and their bit patterns when *
* applicable. They have been taken out of the "EtherLink III Parallel *
* Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
* from 3com. *
* *
**************************************************************************/
#define EP_COMMAND 0x0e /* Write. BASE+0x0e is always a
* command reg. */
#define EP_STATUS 0x0e /* Read. BASE+0x0e is always status
* reg. */
#define EP_WINDOW 0x0f /* Read. BASE+0x0f is always window
* reg. */
/*
* Window 0 registers. Setup.
*/
/* Write */
#define EP_W0_EEPROM_DATA 0x0c
#define EP_W0_EEPROM_COMMAND 0x0a
#define EP_W0_RESOURCE_CFG 0x08
#define EP_W0_ADDRESS_CFG 0x06
#define EP_W0_CONFIG_CTRL 0x04
/* Read */
#define EP_W0_PRODUCT_ID 0x02
#define EP_W0_MFG_ID 0x00
/*
* Window 1 registers. Operating Set.
*/
/* Write */
#define EP_W1_TX_PIO_WR_2 0x02
#define EP_W1_TX_PIO_WR_1 0x00
/* Read */
#define EP_W1_FREE_TX 0x0c
#define EP_W1_TX_STATUS 0x0b /* byte */
#define EP_W1_TIMER 0x0a /* byte */
#define EP_W1_RX_STATUS 0x08
#define EP_W1_RX_PIO_RD_2 0x02
#define EP_W1_RX_PIO_RD_1 0x00
/*
* Window 2 registers. Station Address Setup/Read
*/
/* Read/Write */
#define EP_W2_ADDR_5 0x05
#define EP_W2_ADDR_4 0x04
#define EP_W2_ADDR_3 0x03
#define EP_W2_ADDR_2 0x02
#define EP_W2_ADDR_1 0x01
#define EP_W2_ADDR_0 0x00
/*
* Window 3 registers. FIFO Management.
*/
/* Read */
#define EP_W3_FREE_TX 0x0c
#define EP_W3_FREE_RX 0x0a
/*
* Window 4 registers. Diagnostics.
*/
/* Read/Write */
#define EP_W4_MEDIA_TYPE 0x0a
#define EP_W4_CTRLR_STATUS 0x08
#define EP_W4_NET_DIAG 0x06
#define EP_W4_FIFO_DIAG 0x04
#define EP_W4_HOST_DIAG 0x02
#define EP_W4_TX_DIAG 0x00
/*
* Window 5 Registers. Results and Internal status.
*/
/* Read */
#define EP_W5_READ_0_MASK 0x0c
#define EP_W5_INTR_MASK 0x0a
#define EP_W5_RX_FILTER 0x08
#define EP_W5_RX_EARLY_THRESH 0x06
#define EP_W5_TX_AVAIL_THRESH 0x02
#define EP_W5_TX_START_THRESH 0x00
/*
* Window 6 registers. Statistics.
*/
/* Read/Write */
#define TX_TOTAL_OK 0x0c
#define RX_TOTAL_OK 0x0a
#define TX_DEFERRALS 0x08
#define RX_FRAMES_OK 0x07
#define TX_FRAMES_OK 0x06
#define RX_OVERRUNS 0x05
#define TX_COLLISIONS 0x04
#define TX_AFTER_1_COLLISION 0x03
#define TX_AFTER_X_COLLISIONS 0x02
#define TX_NO_SQE 0x01
#define TX_CD_LOST 0x00
/****************************************
*
* Register definitions.
*
****************************************/
/*
* Command register. All windows.
*
* 16 bit register.
* 15-11: 5-bit code for command to be executed.
* 10-0: 11-bit arg if any. For commands with no args;
* this can be set to anything.
*/
#define GLOBAL_RESET (u_short) 0x0000 /* Wait at least 1ms
* after issuing */
#define WINDOW_SELECT (u_short) (0x1<<11)
#define START_TRANSCEIVER (u_short) (0x2<<11) /* Read ADDR_CFG reg to
* determine whether
* this is needed. If
* so; wait 800 uSec
* before using trans-
* ceiver. */
#define RX_DISABLE (u_short) (0x3<<11) /* state disabled on
* power-up */
#define RX_ENABLE (u_short) (0x4<<11)
#define RX_RESET (u_short) (0x5<<11)
#define RX_DISCARD_TOP_PACK (u_short) (0x8<<11)
#define TX_ENABLE (u_short) (0x9<<11)
#define TX_DISABLE (u_short) (0xa<<11)
#define TX_RESET (u_short) (0xb<<11)
#define REQ_INTR (u_short) (0xc<<11)
#define SET_INTR_MASK (u_short) (0xe<<11)
#define SET_RD_0_MASK (u_short) (0xf<<11)
#define SET_RX_FILTER (u_short) (0x10<<11)
#define FIL_INDIVIDUAL (u_short) (0x1)
#define FIL_GROUP (u_short) (0x2)
#define FIL_BRDCST (u_short) (0x4)
#define FIL_ALL (u_short) (0x8)
#define SET_RX_EARLY_THRESH (u_short) (0x11<<11)
#define SET_TX_AVAIL_THRESH (u_short) (0x12<<11)
#define SET_TX_START_THRESH (u_short) (0x13<<11)
#define STATS_ENABLE (u_short) (0x15<<11)
#define STATS_DISABLE (u_short) (0x16<<11)
#define STOP_TRANSCEIVER (u_short) (0x17<<11)
/*
* The following C_* acknowledge the various interrupts. Some of them don't
* do anything. See the manual.
*/
#define ACK_INTR (u_short) (0x6800)
#define C_INTR_LATCH (u_short) (ACK_INTR|0x1)
#define C_CARD_FAILURE (u_short) (ACK_INTR|0x2)
#define C_TX_COMPLETE (u_short) (ACK_INTR|0x4)
#define C_TX_AVAIL (u_short) (ACK_INTR|0x8)
#define C_RX_COMPLETE (u_short) (ACK_INTR|0x10)
#define C_RX_EARLY (u_short) (ACK_INTR|0x20)
#define C_INT_RQD (u_short) (ACK_INTR|0x40)
#define C_UPD_STATS (u_short) (ACK_INTR|0x80)
/*
* Status register. All windows.
*
* 15-13: Window number(0-7).
* 12: Command_in_progress.
* 11: reserved.
* 10: reserved.
* 9: reserved.
* 8: reserved.
* 7: Update Statistics.
* 6: Interrupt Requested.
* 5: RX Early.
* 4: RX Complete.
* 3: TX Available.
* 2: TX Complete.
* 1: Adapter Failure.
* 0: Interrupt Latch.
*/
#define S_INTR_LATCH (u_short) (0x1)
#define S_CARD_FAILURE (u_short) (0x2)
#define S_TX_COMPLETE (u_short) (0x4)
#define S_TX_AVAIL (u_short) (0x8)
#define S_RX_COMPLETE (u_short) (0x10)
#define S_RX_EARLY (u_short) (0x20)
#define S_INT_RQD (u_short) (0x40)
#define S_UPD_STATS (u_short) (0x80)
#define S_5_INTS (S_CARD_FAILURE|S_TX_COMPLETE|\
S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY)
#define S_COMMAND_IN_PROGRESS (u_short) (0x1000)
/*
* FIFO Registers.
* RX Status. Window 1/Port 08
*
* 15: Incomplete or FIFO empty.
* 14: 1: Error in RX Packet 0: Incomplete or no error.
* 13-11: Type of error.
* 1000 = Overrun.
* 1011 = Run Packet Error.
* 1100 = Alignment Error.
* 1101 = CRC Error.
* 1001 = Oversize Packet Error (>1514 bytes)
* 0010 = Dribble Bits.
* (all other error codes, no errors.)
*
* 10-0: RX Bytes (0-1514)
*/
#define ERR_RX_INCOMPLETE (u_short) (0x1<<15)
#define ERR_RX (u_short) (0x1<<14)
#define ERR_RX_OVERRUN (u_short) (0x8<<11)
#define ERR_RX_RUN_PKT (u_short) (0xb<<11)
#define ERR_RX_ALIGN (u_short) (0xc<<11)
#define ERR_RX_CRC (u_short) (0xd<<11)
#define ERR_RX_OVERSIZE (u_short) (0x9<<11)
#define ERR_RX_DRIBBLE (u_short) (0x2<<11)
/*
* FIFO Registers.
* TX Status. Window 1/Port 0B
*
* Reports the transmit status of a completed transmission. Writing this
* register pops the transmit completion stack.
*
* Window 1/Port 0x0b.
*
* 7: Complete
* 6: Interrupt on successful transmission requested.
* 5: Jabber Error (TP Only, TX Reset required. )
* 4: Underrun (TX Reset required. )
* 3: Maximum Collisions.
* 2: TX Status Overflow.
* 1-0: Undefined.
*
*/
#define TXS_COMPLETE 0x80
#define TXS_SUCCES_INTR_REQ 0x40
#define TXS_JABBER 0x20
#define TXS_UNDERRUN 0x10
#define TXS_MAX_COLLISION 0x8
#define TXS_STATUS_OVERFLOW 0x4
/*
* Configuration control register.
* Window 0/Port 04
*/
/* Read */
#define IS_AUI (1<<13)
#define IS_BNC (1<<12)
#define IS_UTP (1<<9)
/* Write */
#define ENABLE_DRQ_IRQ 0x0001
#define W0_P4_CMD_RESET_ADAPTER 0x4
#define W0_P4_CMD_ENABLE_ADAPTER 0x1
/*
* Media type and status.
* Window 4/Port 0A
*/
#define ENABLE_UTP 0xc0
#define DISABLE_UTP 0x0
/*
* Resource control register
*/
#define SET_IRQ(i) ( ((i)<<12) | 0xF00) /* set IRQ i */
/*
* Receive status register
*/
#define RX_BYTES_MASK (u_short) (0x07ff)
#define RX_ERROR 0x4000
#define RX_INCOMPLETE 0x8000
/*
* Misc defines for various things.
*/
#define ACTIVATE_ADAPTER_TO_CONFIG 0xff /* to the id_port */
#define MFG_ID 0x6d50 /* in EEPROM and W0 ADDR_CONFIG */
#define PROD_ID 0x9150
#define AUI 0x1
#define BNC 0x2
#define UTP 0x4
#define ETHER_ADDR_LEN 6
#define ETHER_MAX 1536
#define RX_BYTES_MASK (u_short) (0x07ff)
/* EISA support */
#define EP_EISA_START 0x1000
#define EP_EISA_W0 0x0c80

View file

@ -0,0 +1,161 @@
/* $NetBSD: 3c590.c,v 1.15 2008/12/14 18:46:33 christos Exp $ */
/* stripped down from freebsd:sys/i386/netboot/3c509.c */
/**************************************************************************
NETBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters.
Date: Mar 22 1995
This code is based heavily on David Greenman's if_ed.c driver and
Andres Vega Garcia's if_ep.c driver.
Copyright (C) 1993-1994, David Greenman, Martin Renters.
Copyright (C) 1993-1995, Andres Vega Garcia.
Copyright (C) 1995, Serge Babkin.
This software may be used, modified, copied, distributed, and sold, in
both source and binary form provided that the above copyright and these
terms are retained. Under no circumstances are the authors responsible for
the proper functioning of this software, nor do the authors assume any
responsibility for damages incurred with its use.
3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
3c509.c,v 1.2 1995/05/30 07:58:52 rgrimes Exp
***************************************************************************/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include <pcivar.h>
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
#include <lib/libkern/libkern.h>
#include <bootinfo.h>
#endif
#include "etherdrv.h"
#include "3c509.h"
#define EP_W3_INTERNAL_CONFIG 0x00 /* 32 bits */
#define EP_W3_RESET_OPTIONS 0x08 /* 16 bits */
unsigned ether_medium;
unsigned short eth_base;
extern void epreset(void);
extern int ep_get_e(int);
u_char eth_myaddr[6];
static struct mtabentry {
int address_cfg; /* configured connector */
int config_bit; /* connector present */
char *name;
} mediatab[] = { /* indexed by media type - etherdrv.h */
{3, 0x10, "BNC"},
{0, 0x08, "UTP"},
{1, 0x20, "AUI"},
{6, 0x40, "MII"},
};
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
static struct btinfo_netif bi_netif;
#endif
/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
int
EtherInit(unsigned char *myadr)
{
/* common variables */
int i, j;
/* variables for 3C509 */
u_short *p;
struct mtabentry *m;
/*********************************************************
Search for 3Com 590 card
***********************************************************/
pcihdl_t hdl;
int iobase;
if (pcicheck() == -1) {
printf("cannot access PCI\n");
return 0;
}
if (pcifinddev(0x10b7, 0x5900, &hdl) &&
pcifinddev(0x10b7, 0x5950, &hdl) &&
pcifinddev(0x10b7, 0x9000, &hdl) &&
pcifinddev(0x10b7, 0x9001, &hdl) &&
pcifinddev(0x10b7, 0x9050, &hdl)) {
printf("cannot find 3c59x / 3c90x\n");
return 0;
}
if (pcicfgread(&hdl, 0x10, &iobase) || !(iobase & 1)) {
printf("cannot map IO space\n");
return 0;
}
eth_base = iobase & 0xfffffffc;
/* test for presence of connectors */
GO_WINDOW(3);
i = inb(IS_BASE + EP_W3_RESET_OPTIONS);
j = (inw(IS_BASE + EP_W3_INTERNAL_CONFIG + 2) >> 4) & 7;
GO_WINDOW(0);
for (ether_medium = 0, m = mediatab;
ether_medium < sizeof(mediatab) / sizeof(mediatab[0]);
ether_medium++, m++) {
if (j == m->address_cfg) {
if (!(i & m->config_bit)) {
printf("%s not present\n", m->name);
return 0;
}
printf("using %s\n", m->name);
goto ok;
}
}
printf("unknown connector\n");
return 0;
ok:
/*
* Read the station address from the eeprom
*/
p = (u_short *) eth_myaddr;
for (i = 0; i < 3; i++) {
u_short help;
GO_WINDOW(0);
help = ep_get_e(i);
p[i] = ((help & 0xff) << 8) | ((help & 0xff00) >> 8);
GO_WINDOW(2);
outw(BASE + EP_W2_ADDR_0 + (i * 2), help);
}
for (i = 0; i < 6; i++)
myadr[i] = eth_myaddr[i];
epreset();
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
strncpy(bi_netif.ifname, "ep", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_PCI;
bi_netif.addr.tag = hdl;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
#endif
return 1;
}

View file

@ -0,0 +1,449 @@
/* $NetBSD: 3c90xb.c,v 1.14 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1999
* Matthias Drochner. 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.
*/
#include <sys/types.h>
#include <machine/pio.h>
struct mbuf; /* XXX */
typedef int bus_dmamap_t; /* XXX */
#include <dev/ic/elink3reg.h>
#include <dev/ic/elinkxlreg.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include <pcivar.h>
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
#include <lib/libkern/libkern.h>
#include <bootinfo.h>
#endif
#include "etherdrv.h"
#define RECVBUF_SIZE 1600 /* struct ex_upd + packet */
#ifdef _STANDALONE
static pcihdl_t mytag;
static char recvbuf[RECVBUF_SIZE];
#define RECVBUF_PHYS vtophys(recvbuf)
#define RECVBUF_VIRT ((void *)recvbuf)
static struct ex_dpd sndbuf;
#define SNDBUF_PHYS vtophys(&sndbuf)
#define SNDBUF_VIRT ((void *)&sndbuf)
#else /* !standalone, userspace testing environment */
#define PCI_MODE1_ENABLE 0x80000000UL
#define PCIBUSNO 1
#define PCIDEVNO 4
static pcihdl_t mytag = PCI_MODE1_ENABLE | (PCIBUSNO << 16) | (PCIDEVNO << 11);
extern void *mapmem(int, int);
void *dmamem; /* virtual */
#define DMABASE 0x3ffd800
#define DMASIZE 10240
#define RECVBUF_PHYS DMABASE
#define RECVBUF_VIRT dmamem
#define SNDBUF_PHYS (DMABASE + RECVBUF_SIZE)
#define SNDBUF_VIRT ((void *)(((char *)dmamem) + RECVBUF_SIZE))
#endif /* _STANDALONE */
#define CSR_READ_1(reg) inb(iobase + (reg))
#define CSR_READ_2(reg) inw(iobase + (reg))
#define CSR_READ_4(reg) inl(iobase + (reg))
#define CSR_WRITE_1(reg, val) outb(iobase + (reg), val)
#define CSR_WRITE_2(reg, val) outw(iobase + (reg), val)
#define CSR_WRITE_4(reg, val) outl(iobase + (reg), val)
#undef GO_WINDOW
#define GO_WINDOW(x) CSR_WRITE_2(ELINK_COMMAND, WINDOW_SELECT | x)
static int iobase;
static u_char myethaddr[6];
unsigned ether_medium;
static struct {
int did;
int mii;
} excards[] = {
{0x9005, 0}, /* 3c900b Combo */
{0x9055, 1}, /* 3c905b TP */
{0x9058, 0}, /* 3c905b Combo */
{-1}
}, *excard;
static struct mtabentry {
int address_cfg; /* configured connector */
int config_bit; /* connector present */
char *name;
} mediatab[] = { /* indexed by media type - etherdrv.h */
{ELINKMEDIA_10BASE_2, ELINK_PCI_BNC, "BNC"},
{ELINKMEDIA_10BASE_T, ELINK_PCI_10BASE_T, "UTP"},
{ELINKMEDIA_AUI, ELINK_PCI_AUI, "AUI"},
{ELINKMEDIA_MII, ELINK_PCI_100BASE_MII, "MII"},
{ELINKMEDIA_100BASE_TX, ELINK_PCI_100BASE_TX, "100TX"},
};
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
static struct btinfo_netif bi_netif;
#endif
#define ex_waitcmd() \
do { \
while (CSR_READ_2(ELINK_STATUS) & COMMAND_IN_PROGRESS) \
continue; \
} while (0)
void ex_reset(void);
uint16_t ex_read_eeprom(int);
static int ex_eeprom_busy(void);
void ex_init(void);
void ex_set_media(void);
void
ex_reset(void)
{
CSR_WRITE_2(ELINK_COMMAND, GLOBAL_RESET);
delay(100000);
ex_waitcmd();
}
/*
* Read EEPROM data.
* XXX what to do if EEPROM doesn't unbusy?
*/
uint16_t
ex_read_eeprom(int offset)
{
uint16_t data = 0;
GO_WINDOW(0);
if (ex_eeprom_busy())
goto out;
CSR_WRITE_1(ELINK_W0_EEPROM_COMMAND, READ_EEPROM | (offset & 0x3f));
if (ex_eeprom_busy())
goto out;
data = CSR_READ_2(ELINK_W0_EEPROM_DATA);
out:
return data;
}
static int
ex_eeprom_busy(void)
{
int i = 100;
while (i--) {
if (!(CSR_READ_2(ELINK_W0_EEPROM_COMMAND) & EEPROM_BUSY))
return 0;
delay(100);
}
printf("\nex: eeprom stays busy.\n");
return 1;
}
/*
* Bring device up.
*/
void
ex_init(void)
{
int i;
ex_waitcmd();
EtherStop();
/*
* Set the station address and clear the station mask. The latter
* is needed for 90x cards, 0 is the default for 90xB cards.
*/
GO_WINDOW(2);
for (i = 0; i < 6; i++) {
CSR_WRITE_1(ELINK_W2_ADDR_0 + i,
myethaddr[i]);
CSR_WRITE_1(ELINK_W2_RECVMASK_0 + i, 0);
}
GO_WINDOW(3);
CSR_WRITE_2(ELINK_COMMAND, RX_RESET);
ex_waitcmd();
CSR_WRITE_2(ELINK_COMMAND, TX_RESET);
ex_waitcmd();
CSR_WRITE_2(ELINK_COMMAND, SET_INTR_MASK | 0); /* disable */
CSR_WRITE_2(ELINK_COMMAND, ACK_INTR | 0xff);
ex_set_media();
CSR_WRITE_2(ELINK_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST);
CSR_WRITE_4(ELINK_DNLISTPTR, 0);
CSR_WRITE_2(ELINK_COMMAND, TX_ENABLE);
CSR_WRITE_4(ELINK_UPLISTPTR, RECVBUF_PHYS);
CSR_WRITE_2(ELINK_COMMAND, RX_ENABLE);
CSR_WRITE_2(ELINK_COMMAND, ELINK_UPUNSTALL);
GO_WINDOW(1);
}
void
ex_set_media(void)
{
int config0, config1;
CSR_WRITE_2(ELINK_W3_MAC_CONTROL, 0);
if (ether_medium == ETHERMEDIUM_MII)
goto setcfg;
GO_WINDOW(4);
CSR_WRITE_2(ELINK_W4_MEDIA_TYPE, 0);
CSR_WRITE_2(ELINK_COMMAND, STOP_TRANSCEIVER);
delay(800);
switch (ether_medium) {
case ETHERMEDIUM_UTP:
CSR_WRITE_2(ELINK_W4_MEDIA_TYPE,
JABBER_GUARD_ENABLE | LINKBEAT_ENABLE);
break;
case ETHERMEDIUM_BNC:
CSR_WRITE_2(ELINK_COMMAND, START_TRANSCEIVER);
delay(800);
break;
case ETHERMEDIUM_AUI:
CSR_WRITE_2(ELINK_W4_MEDIA_TYPE, SQE_ENABLE);
delay(800);
break;
case ETHERMEDIUM_100TX:
CSR_WRITE_2(ELINK_W4_MEDIA_TYPE, LINKBEAT_ENABLE);
break;
}
setcfg:
GO_WINDOW(3);
config0 = CSR_READ_2(ELINK_W3_INTERNAL_CONFIG);
config1 = CSR_READ_2(ELINK_W3_INTERNAL_CONFIG + 2);
config1 = config1 & ~CONFIG_MEDIAMASK;
config1 |= (mediatab[ether_medium].address_cfg
<< CONFIG_MEDIAMASK_SHIFT);
CSR_WRITE_2(ELINK_W3_INTERNAL_CONFIG, config0);
CSR_WRITE_2(ELINK_W3_INTERNAL_CONFIG + 2, config1);
}
static void
ex_probemedia(void)
{
int i, j;
struct mtabentry *m;
/* test for presence of connectors */
GO_WINDOW(3);
i = CSR_READ_1(ELINK_W3_RESET_OPTIONS);
j = (CSR_READ_2(ELINK_W3_INTERNAL_CONFIG + 2) & CONFIG_MEDIAMASK)
>> CONFIG_MEDIAMASK_SHIFT;
GO_WINDOW(0);
for (ether_medium = 0, m = mediatab;
ether_medium < sizeof(mediatab) / sizeof(mediatab[0]);
ether_medium++, m++) {
if (j == m->address_cfg) {
if (!(i & m->config_bit)) {
printf("%s not present\n", m->name);
goto bad;
}
printf("using %s\n", m->name);
return;
}
}
printf("unknown connector\n");
bad:
ether_medium = -1;
}
int
EtherInit(unsigned char *myadr)
{
uint32_t pcicsr;
uint16_t val;
volatile struct ex_upd *upd;
#ifndef _STANDALONE
uint32_t id;
#endif
if (pcicheck()) {
printf("pcicheck failed\n");
return 0;
}
#ifndef _STANDALONE
pcicfgread(&mytag, 0, &id);
#endif
for (excard = &excards[0]; excard->did != -1; excard++) {
#ifdef _STANDALONE
if (pcifinddev(0x10b7, excard->did, &mytag) == 0)
goto found;
#else
if (id == (0x10b7 | (excard->did << 16)))
goto found;
#endif
}
printf("no ex\n");
return 0;
found:
pcicfgread(&mytag, 0x10, &iobase);
iobase &= ~3;
#ifndef _STANDALONE
dmamem = mapmem(DMABASE, DMASIZE);
if (!dmamem)
return 0;
#endif
/* enable bus mastering in PCI command register */
if (pcicfgread(&mytag, 0x04, (int *)&pcicsr)
|| pcicfgwrite(&mytag, 0x04, pcicsr | 4)) {
printf("cannot enable DMA\n");
return 0;
}
ex_reset();
if (excard->mii)
ether_medium = ETHERMEDIUM_MII;
else {
ex_probemedia();
if (ether_medium < 0)
return 0;
}
val = ex_read_eeprom(EEPROM_OEM_ADDR0);
myethaddr[0] = val >> 8;
myethaddr[1] = val & 0xff;
val = ex_read_eeprom(EEPROM_OEM_ADDR1);
myethaddr[2] = val >> 8;
myethaddr[3] = val & 0xff;
val = ex_read_eeprom(EEPROM_OEM_ADDR2);
myethaddr[4] = val >> 8;
myethaddr[5] = val & 0xff;
memcpy(myadr, myethaddr, 6);
upd = RECVBUF_VIRT;
upd->upd_nextptr = RECVBUF_PHYS;
upd->upd_pktstatus = 1500;
upd->upd_frags[0].fr_addr = RECVBUF_PHYS + 100;
upd->upd_frags[0].fr_len = 1500 | EX_FR_LAST;
ex_init();
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
strncpy(bi_netif.ifname, "ex", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_PCI;
bi_netif.addr.tag = mytag;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
#endif
return 1;
}
void
EtherStop(void)
{
/*
* Issue software reset
*/
CSR_WRITE_2(ELINK_COMMAND, RX_DISABLE);
CSR_WRITE_2(ELINK_COMMAND, TX_DISABLE);
CSR_WRITE_2(ELINK_COMMAND, STOP_TRANSCEIVER);
CSR_WRITE_2(ELINK_COMMAND, INTR_LATCH);
}
int
EtherSend(char *pkt, int len)
{
volatile struct ex_dpd *dpd;
int i;
dpd = SNDBUF_VIRT;
dpd->dpd_nextptr = 0;
dpd->dpd_fsh = len;
#ifdef _STANDALONE
dpd->dpd_frags[0].fr_addr = vtophys(pkt);
#else
memcpy(SNDBUF_VIRT + 100, pkt, len);
dpd->dpd_frags[0].fr_addr = SNDBUF_PHYS + 100;
#endif
dpd->dpd_frags[0].fr_len = len | EX_FR_LAST;
CSR_WRITE_4(ELINK_DNLISTPTR, SNDBUF_PHYS);
CSR_WRITE_2(ELINK_COMMAND, ELINK_DNUNSTALL);
i = 10000;
while (!(dpd->dpd_fsh & 0x00010000)) {
if (--i < 0) {
printf("3c90xb: send timeout\n");
return -1;
}
delay(1);
}
return len;
}
int
EtherReceive(char *pkt, int maxlen)
{
volatile struct ex_upd *upd;
int len;
upd = RECVBUF_VIRT;
if (!(upd->upd_pktstatus & ~EX_UPD_PKTLENMASK))
return 0;
len = upd->upd_pktstatus & EX_UPD_PKTLENMASK;
if (len > maxlen)
len = 0;
else
memcpy(pkt, RECVBUF_VIRT + 100, len);
upd->upd_pktstatus = 1500;
CSR_WRITE_2(ELINK_COMMAND, ELINK_UPUNSTALL);
return len;
}

View file

@ -0,0 +1,36 @@
## $NetBSD: Makefile.inc,v 1.6 2002/02/17 20:03:11 thorpej Exp $
SRCS+= netif_small.c
.if (${USE_NETIF} == "3c509")
SRCS+= 3c509.c elink3.c
.endif
.if (${USE_NETIF} == "3c590")
SRCS+= 3c590.c elink3.c
.endif
.if (${USE_NETIF} == "wd80x3")
SRCS+= wd80x3.c dp8390.c
.endif
.if (${USE_NETIF} == "pcnet_pci")
SRCS+= pcnet_pci.c am7990.c
.endif
.if (${USE_NETIF} == "pcnet_isapnp")
SRCS+= pcnet_isapnp.c am7990.c
.endif
.if (${USE_NETIF} == "i82557")
SRCS+= i82557.c
.endif
.if (${USE_NETIF} == "3c90xb")
SRCS+= 3c90xb.c
.endif
.if (${USE_NETIF} == "ne2000_isa")
SRCS+= ne.c dp8390.c
CPPFLAGS+= -DSUPPORT_NE2000
.endif

View file

@ -0,0 +1,280 @@
/* $NetBSD: am7990.c,v 1.7 2008/12/14 18:46:33 christos Exp $ */
/* mostly from netbsd:sys/arch/i386/netboot/ne2100.c
memory allocation now 1 chunk, added deallocation
receive function changed - don't use irq
*/
/*
* source in this file came from
* the Mach ethernet boot written by Leendert van Doorn.
*
* A very simple network driver for NE2100 boards that polls.
*
* Copyright (c) 1992 by Leendert van Doorn
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libkern/libkern.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include "etherdrv.h"
#include "lance.h"
extern u_char eth_myaddr[6];
extern int lance_rap, lance_rdp;
static void *dmamem;
#define LA(adr) vtophys(adr)
/* Lance register offsets */
#define LA_CSR lance_rdp
#define LA_CSR1 lance_rdp
#define LA_CSR2 lance_rdp
#define LA_CSR3 lance_rdp
#define LA_RAP lance_rap
/*
* Some driver specific constants.
* Take care when tuning, this program only has 32 Kb
*/
#define LANCEBUFSIZE 1518 /* plus 4 CRC bytes */
#define MAXLOOP 1000000L /* arbitrary retry limit */
#define LOG2NRCVRING 2 /* log2(NRCVRING) */
#define NRCVRING (1 << LOG2NRCVRING)
static int next_rmd; /* next receive element */
static initblock_t *initblock; /* initialization block */
static tmde_t *tmd; /* transmit ring */
static rmde_t *rmd; /* receive ring */
static char rbuffer[NRCVRING][LANCEBUFSIZE]; /* receive buffers */
/*
* Stop ethernet board
*/
void
am7990_stop(void)
{
long l;
/* stop chip and disable DMA access */
outw(LA_RAP, RDP_CSR0);
outw(LA_CSR, CSR_STOP);
for (l = 0; (inw(LA_CSR) & CSR_STOP) == 0; l++) {
if (l >= MAXLOOP) {
printf("Lance failed to stop\n");
return;
}
}
}
/*
* Reset ethernet board
*/
void
am7990_init(void)
{
long l;
u_long addr;
int i;
/* initblock, tmd, and rmd should be 8 byte aligned;
sizes of initblock_t and tmde_t are multiples of 8 */
dmamem = alloc(sizeof(initblock_t) +
sizeof(tmde_t) + NRCVRING * sizeof(rmde_t) + 4);
/* +4 is ok because alloc()'s result is 4-byte aligned! */
initblock = (initblock_t *)(((unsigned long)dmamem + 4) & -8);
tmd = (tmde_t *)(initblock + 1);
rmd = (rmde_t *)(tmd + 1);
/* stop the chip, and make sure it did */
am7990_stop();
/* fill lance initialization block */
memset(initblock, 0, sizeof(initblock_t));
/* set my ethernet address */
for (i = 0; i < 6; i++)
initblock->ib_padr[i] = eth_myaddr[i];
/* receive ring pointer */
addr = LA(rmd);
initblock->ib_rdralow = (u_short)addr;
initblock->ib_rdrahigh = (u_char)(addr >> 16);
initblock->ib_rlen = LOG2NRCVRING << 5;
/* transmit ring with one element */
addr = LA(tmd);
initblock->ib_tdralow = (u_short)addr;
initblock->ib_tdrahigh = (u_char)(addr >> 16);
initblock->ib_tlen = 0 << 5;
/* setup the receive ring entries */
for (next_rmd = 0, i = 0; i < NRCVRING; i++) {
addr = LA(&rbuffer[i]);
rmd[i].rmd_ladr = (u_short)addr;
rmd[i].rmd_hadr = (u_char)(addr >> 16);
rmd[i].rmd_mcnt = 0;
rmd[i].rmd_bcnt = -LANCEBUFSIZE;
rmd[i].rmd_flags = RMD_OWN;
}
/* zero transmit ring */
memset(tmd, 0, sizeof(tmde_t));
/* give lance the init block */
addr = LA(initblock);
outw(LA_RAP, RDP_CSR1);
outw(LA_CSR1, (u_short)addr);
outw(LA_RAP, RDP_CSR2);
outw(LA_CSR2, (char)(addr >> 16));
outw(LA_RAP, RDP_CSR3);
outw(LA_CSR3, 0);
/* and initialize it */
outw(LA_RAP, RDP_CSR0);
outw(LA_CSR, CSR_INIT|CSR_STRT);
/* wait for the lance to complete initialization and fire it up */
for (l = 0; (inw(LA_CSR) & CSR_IDON) == 0; l++) {
if (l >= MAXLOOP) {
printf("Lance failed to initialize\n");
break;
}
}
for (l = 0; (inw(LA_CSR)&(CSR_TXON|CSR_RXON)) != (CSR_TXON|CSR_RXON); l++) {
if (l >= MAXLOOP) {
printf("Lance not started\n");
break;
}
}
}
/*
* Stop ethernet board and free ressources
*/
void
EtherStop(void)
{
am7990_stop();
dealloc(dmamem, sizeof(initblock_t) +
sizeof(tmde_t) + NRCVRING * sizeof(rmde_t) + 4);
}
/*
* Send an ethernet packet
*/
int
EtherSend(char *pkt, int len)
{
long l;
u_long addr;
u_short csr;
int savlen = len;
if (len < 60)
len = 60;
if (len > LANCEBUFSIZE) {
printf("packet too long\n");
return -1;
}
/* set up transmit ring element */
if (tmd->tmd_flags & TMD_OWN) {
printf("lesend: td busy, status=%x\n", tmd->tmd_flags);
return -1;
}
addr = LA(pkt);
if (addr & 1) {
printf("unaligned data\n");
return -1;
}
tmd->tmd_ladr = (u_short)addr;
tmd->tmd_hadr = (u_char)(addr >> 16);
tmd->tmd_bcnt = -len;
tmd->tmd_err = 0;
tmd->tmd_flags = TMD_OWN|TMD_STP|TMD_ENP;
/* start transmission */
outw(LA_CSR, CSR_TDMD);
/* wait for interrupt and acknowledge it */
for (l = 0; l < MAXLOOP; l++) {
if ((csr = inw(LA_CSR)) & CSR_TINT) {
outw(LA_CSR, CSR_TINT);
#ifdef LEDEBUG
if (tmd->tmd_flags & (TMD_ONE|TMD_MORE|TMD_ERR|TMD_DEF))
printf("lesend: status=%x\n", tmd->tmd_flags);
#endif
break;
}
delay(10); /* don't poll too much on PCI, seems
to disturb DMA on poor hardware */
}
return savlen;
}
/*
* Poll the LANCE just see if there's an Ethernet packet
* available. If there is, its contents is returned.
*/
int
EtherReceive(char *pkt, int maxlen)
{
rmde_t *rp;
u_short csr;
int len = 0;
csr = inw(LA_CSR);
outw(LA_CSR, csr & (CSR_BABL | CSR_MISS | CSR_MERR | CSR_RINT));
if ((next_rmd < 0) || (next_rmd >= NRCVRING)) {
printf("next_rmd bad\n");
return 0;
}
rp = &rmd[next_rmd];
if (rp->rmd_flags & RMD_OWN)
return 0;
if (csr & (CSR_BABL | CSR_CERR | CSR_MISS | CSR_MERR))
printf("le: csr %x\n", csr);
if (rp->rmd_flags & (RMD_FRAM | RMD_OFLO | RMD_CRC | RMD_BUFF)) {
printf("le: rmd_flags %x\n", rp->rmd_flags);
goto cleanup;
}
if (rp->rmd_flags != (RMD_STP|RMD_ENP)) {
printf("le: rmd_flags %x\n", rp->rmd_flags);
return -1;
}
len = rp->rmd_mcnt - 4;
if ((len < 0) || (len >= LANCEBUFSIZE)) {
printf("bad pkt len\n");
return -1;
}
if (len <= maxlen)
memcpy(pkt, rbuffer[next_rmd], len);
else
len = 0;
cleanup:
/* give packet back to the lance */
rp->rmd_bcnt = -LANCEBUFSIZE;
rp->rmd_mcnt = 0;
rp->rmd_flags = RMD_OWN;
next_rmd = (next_rmd + 1) & (NRCVRING - 1);
return len;
}

View file

@ -0,0 +1,362 @@
/* $NetBSD: dp8390.c,v 1.6 2008/12/14 18:46:33 christos Exp $ */
/*
* Polling driver for National Semiconductor DS8390/WD83C690 based
* ethernet adapters.
*
* Copyright (c) 1998 Matthias Drochner. All rights reserved.
*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
*
* Copyright (C) 1993, David Greenman. This software may be used, modified,
* copied, distributed, and sold, in both source and binary form provided that
* the above copyright and these terms are retained. Under no circumstances is
* the author responsible for the proper functioning of this software, nor does
* the author assume any responsibility for damages incurred with its use.
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include <dev/ic/dp8390reg.h>
#include "dp8390.h"
#ifdef SUPPORT_NE2000
#include "ne.h"
#endif
#include "etherdrv.h"
int dp8390_iobase, dp8390_membase, dp8390_memsize;
#if defined(SUPPORT_WD80X3) && defined(SUPPORT_SMC_ULTRA)
int dp8390_is790;
#endif
uint8_t dp8390_cr_proto;
uint8_t dp8390_dcr_reg;
#define WE_IOBASE dp8390_iobase
static u_short rec_page_start;
static u_short rec_page_stop;
static u_short next_packet;
extern u_char eth_myaddr[6];
#ifndef _STANDALONE
static void *vmembase;
extern void *mapmem(int, int);
extern void unmapmem(void *, int);
extern int mapio(void);
static void
bbcopy(void *src, void *dst, int len)
{
char *s = (char *)src;
char *d = (char *)dst;
while (len--)
*d++ = *s++;
}
#endif
static void dp8390_read(int, char *, u_short);
#define NIC_GET(reg) inb(WE_IOBASE + reg)
#define NIC_PUT(reg, val) outb(WE_IOBASE + reg, val)
static void
dp8390_init(void)
{
int i;
/*
* Initialize the NIC in the exact order outlined in the NS manual.
* This init procedure is "mandatory"...don't change what or when
* things happen.
*/
/* Set interface for page 0, remote DMA complete, stopped. */
NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
if (dp8390_dcr_reg & ED_DCR_LS) {
NIC_PUT(ED_P0_DCR, dp8390_dcr_reg);
} else {
/*
* Set FIFO threshold to 8, No auto-init Remote DMA, byte
* order=80x86, byte-wide DMA xfers,
*/
NIC_PUT(ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
}
/* Clear remote byte count registers. */
NIC_PUT(ED_P0_RBCR0, 0);
NIC_PUT(ED_P0_RBCR1, 0);
/* Tell RCR to do nothing for now. */
NIC_PUT(ED_P0_RCR, ED_RCR_MON);
/* Place NIC in internal loopback mode. */
NIC_PUT(ED_P0_TCR, ED_TCR_LB0);
/* Set lower bits of byte addressable framing to 0. */
if (dp8390_is790)
NIC_PUT(0x09, 0);
/* Initialize receive buffer ring. */
NIC_PUT(ED_P0_BNRY, rec_page_start);
NIC_PUT(ED_P0_PSTART, rec_page_start);
NIC_PUT(ED_P0_PSTOP, rec_page_stop);
/*
* Clear all interrupts. A '1' in each bit position clears the
* corresponding flag.
*/
NIC_PUT(ED_P0_ISR, 0xff);
/*
* Disable all interrupts.
*/
NIC_PUT(ED_P0_IMR, 0);
/* Program command register for page 1. */
NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
/* Copy out our station address. */
for (i = 0; i < 6; ++i)
NIC_PUT(ED_P1_PAR0 + i, eth_myaddr[i]);
/*
* Set current page pointer to one page after the boundary pointer, as
* recommended in the National manual.
*/
next_packet = rec_page_start + 1;
NIC_PUT(ED_P1_CURR, next_packet);
/* Program command register for page 0. */
NIC_PUT(ED_P1_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
/* directed and broadcast */
NIC_PUT(ED_P0_RCR, ED_RCR_AB);
/* Take interface out of loopback. */
NIC_PUT(ED_P0_TCR, 0);
/* Fire up the interface. */
NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
}
int
dp8390_config(void)
{
#ifndef _STANDALONE
if (mapio()) {
printf("no IO access\n");
return -1;
}
vmembase = mapmem(dp8390_membase, dp8390_memsize);
if (!vmembase) {
printf("no memory access\n");
return -1;
}
#endif
rec_page_start = TX_PAGE_START + ED_TXBUF_SIZE;
rec_page_stop = TX_PAGE_START + (dp8390_memsize >> ED_PAGE_SHIFT);
dp8390_init();
return 0;
}
void
dp8390_stop(void)
{
int n = 5000;
/* Stop everything on the interface, and select page 0 registers. */
NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
/*
* Wait for interface to enter stopped state, but limit # of checks to
* 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but
* just in case it's an old one.
*/
while (((NIC_GET(ED_P0_ISR) & ED_ISR_RST) == 0) && --n)
continue;
#ifndef _STANDALONE
unmapmem(vmembase, dp8390_memsize);
#endif
}
int
EtherSend(char *pkt, int len)
{
#ifdef SUPPORT_NE2000
ne2000_writemem(pkt, dp8390_membase, len);
#else
#ifdef _STANDALONE
vpbcopy(pkt, (void *)dp8390_membase, len);
#else
bbcopy(pkt, vmembase, len);
#endif
#endif
/* Set TX buffer start page. */
NIC_PUT(ED_P0_TPSR, TX_PAGE_START);
/* Set TX length. */
NIC_PUT(ED_P0_TBCR0, len < 60 ? 60 : len);
NIC_PUT(ED_P0_TBCR1, len >> 8);
/* Set page 0, remote DMA complete, transmit packet, and *start*. */
NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
return len;
}
static void
dp8390_read(int buf, char *dest, u_short len)
{
u_short tmp_amount;
/* Does copy wrap to lower addr in ring buffer? */
if (buf + len > dp8390_membase + dp8390_memsize) {
tmp_amount = dp8390_membase + dp8390_memsize - buf;
/* Copy amount up to end of NIC memory. */
#ifdef SUPPORT_NE2000
ne2000_readmem(buf, dest, tmp_amount);
#else
#ifdef _STANDALONE
pvbcopy((void *)buf, dest, tmp_amount);
#else
bbcopy(vmembase + buf - dp8390_membase, dest, tmp_amount);
#endif
#endif
len -= tmp_amount;
buf = RX_BUFBASE + (rec_page_start << ED_PAGE_SHIFT);
dest += tmp_amount;
}
#ifdef SUPPORT_NE2000
ne2000_readmem(buf, dest, len);
#else
#ifdef _STANDALONE
pvbcopy((void *)buf, dest, len);
#else
bbcopy(vmembase + buf - dp8390_membase, dest, len);
#endif
#endif
}
int
EtherReceive(char *pkt, int maxlen)
{
struct dp8390_ring packet_hdr;
int packet_ptr;
u_short len;
u_char boundary, current;
#ifdef DP8390_OLDCHIPS
u_char nlen;
#endif
if (!(NIC_GET(ED_P0_RSR) & ED_RSR_PRX))
return 0; /* XXX error handling */
/* Set NIC to page 1 registers to get 'current' pointer. */
NIC_PUT(ED_P0_CR, dp8390_cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
/*
* 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
* it points to where new data has been buffered. The 'CURR' (current)
* register points to the logical end of the ring-buffer - i.e. it
* points to where additional new data will be added. We loop here
* until the logical beginning equals the logical end (or in other
* words, until the ring-buffer is empty).
*/
current = NIC_GET(ED_P1_CURR);
/* Set NIC to page 0 registers to update boundary register. */
NIC_PUT(ED_P1_CR, dp8390_cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
if (next_packet == current)
return 0;
/* Get pointer to this buffer's header structure. */
packet_ptr = RX_BUFBASE + (next_packet << ED_PAGE_SHIFT);
/*
* The byte count includes a 4 byte header that was added by
* the NIC.
*/
#ifdef SUPPORT_NE2000
ne2000_readmem(packet_ptr, (void *)&packet_hdr, 4);
#else
#ifdef _STANDALONE
pvbcopy((void *)packet_ptr, &packet_hdr, 4);
#else
bbcopy(vmembase + packet_ptr - dp8390_membase, &packet_hdr, 4);
#endif
#endif
len = packet_hdr.count;
#ifdef DP8390_OLDCHIPS
/*
* Try do deal with old, buggy chips that sometimes duplicate
* the low byte of the length into the high byte. We do this
* by simply ignoring the high byte of the length and always
* recalculating it.
*
* NOTE: sc->next_packet is pointing at the current packet.
*/
if (packet_hdr.next_packet >= next_packet)
nlen = (packet_hdr.next_packet - next_packet);
else
nlen = ((packet_hdr.next_packet - rec_page_start) +
(rec_page_stop - next_packet));
--nlen;
if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
--nlen;
len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
#ifdef DIAGNOSTIC
if (len != packet_hdr.count) {
printf(IFNAME ": length does not match next packet pointer\n");
printf(IFNAME ": len %04x nlen %04x start %02x "
"first %02x curr %02x next %02x stop %02x\n",
packet_hdr.count, len,
rec_page_start, next_packet, current,
packet_hdr.next_packet, rec_page_stop);
}
#endif
#endif
if (packet_hdr.next_packet < rec_page_start ||
packet_hdr.next_packet >= rec_page_stop)
panic(IFNAME ": RAM corrupt");
len -= sizeof(struct dp8390_ring);
if (len < maxlen) {
/* Go get packet. */
dp8390_read(packet_ptr + sizeof(struct dp8390_ring),
pkt, len);
} else
len = 0;
/* Update next packet pointer. */
next_packet = packet_hdr.next_packet;
/*
* Update NIC boundary pointer - being careful to keep it one
* buffer behind (as recommended by NS databook).
*/
boundary = next_packet - 1;
if (boundary < rec_page_start)
boundary = rec_page_stop - 1;
NIC_PUT(ED_P0_BNRY, boundary);
return len;
}

View file

@ -0,0 +1,33 @@
/* $NetBSD: dp8390.h,v 1.6 2008/12/14 18:46:33 christos Exp $ */
extern int dp8390_config(void);
extern void dp8390_stop(void);
extern int dp8390_iobase;
extern int dp8390_membase;
extern int dp8390_memsize;
#ifdef SUPPORT_WD80X3
#ifdef SUPPORT_SMC_ULTRA
extern int dp8390_is790;
#else
#define dp8390_is790 0
#endif
#else
#ifdef SUPPORT_SMC_ULTRA
#define dp8390_is790 1
#endif
#endif
#ifdef SUPPORT_NE2000
#define dp8390_is790 0
#define IFNAME "ne"
#define RX_BUFBASE 0
#define TX_PAGE_START (dp8390_membase >> ED_PAGE_SHIFT)
#else
#define IFNAME "we"
#define RX_BUFBASE dp8390_membase
#define TX_PAGE_START 0
#endif
extern uint8_t dp8390_cr_proto; /* values always set in CR */
extern uint8_t dp8390_dcr_reg; /* override DCR if LS is set */

View file

@ -0,0 +1,336 @@
/* $NetBSD: elink3.c,v 1.4 2008/12/14 18:46:33 christos Exp $ */
/* stripped down from freebsd:sys/i386/netboot/3c509.c */
/**************************************************************************
NETBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters.
Date: Mar 22 1995
This code is based heavily on David Greenman's if_ed.c driver and
Andres Vega Garcia's if_ep.c driver.
Copyright (C) 1993-1994, David Greenman, Martin Renters.
Copyright (C) 1993-1995, Andres Vega Garcia.
Copyright (C) 1995, Serge Babkin.
This software may be used, modified, copied, distributed, and sold, in
both source and binary form provided that the above copyright and these
terms are retained. Under no circumstances are the authors responsible for
the proper functioning of this software, nor do the authors assume any
responsibility for damages incurred with its use.
3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
3c509.c,v 1.2 1995/05/30 07:58:52 rgrimes Exp
***************************************************************************/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include "etherdrv.h"
#include "3c509.h"
extern unsigned short eth_base;
extern u_char eth_myaddr[6];
void
epstop(void)
{
/* stop card */
outw(BASE + EP_COMMAND, RX_DISABLE);
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
outw(BASE + EP_COMMAND, TX_DISABLE);
outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
outw(BASE + EP_COMMAND, RX_RESET);
outw(BASE + EP_COMMAND, TX_RESET);
outw(BASE + EP_COMMAND, C_INTR_LATCH);
outw(BASE + EP_COMMAND, SET_RD_0_MASK);
outw(BASE + EP_COMMAND, SET_INTR_MASK);
outw(BASE + EP_COMMAND, SET_RX_FILTER);
}
void
EtherStop(void)
{
epstop();
outw(BASE + EP_COMMAND, GLOBAL_RESET);
delay(100000);
}
/**************************************************************************
ETH_RESET - Reset adapter
***************************************************************************/
void
epreset(void)
{
int i;
/***********************************************************
Reset 3Com 509 card
*************************************************************/
epstop();
/*
* initialize card
*/
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
continue;
GO_WINDOW(0);
/* Disable the card */
outw(BASE + EP_W0_CONFIG_CTRL, 0);
/* Configure IRQ to none */
outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(0));
/* Enable the card */
outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
GO_WINDOW(2);
/* Reload the ether_addr. */
for (i = 0; i < 6; i++)
outb(BASE + EP_W2_ADDR_0 + i, eth_myaddr[i]);
outw(BASE + EP_COMMAND, RX_RESET);
outw(BASE + EP_COMMAND, TX_RESET);
/* Window 1 is operating window */
GO_WINDOW(1);
for (i = 0; i < 31; i++)
inb(BASE + EP_W1_TX_STATUS);
/* get rid of stray intr's */
outw(BASE + EP_COMMAND, ACK_INTR | 0xff);
outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_5_INTS);
outw(BASE + EP_COMMAND, SET_INTR_MASK);
outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
FIL_BRDCST);
/* configure BNC */
if (ether_medium == ETHERMEDIUM_BNC) {
outw(BASE + EP_COMMAND, START_TRANSCEIVER);
delay(1000);
}
/* configure UTP */
if (ether_medium == ETHERMEDIUM_UTP) {
GO_WINDOW(4);
outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
GO_WINDOW(1);
}
/* start tranciever and receiver */
outw(BASE + EP_COMMAND, RX_ENABLE);
outw(BASE + EP_COMMAND, TX_ENABLE);
/* set early threshold for minimal packet length */
outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | 64);
outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);
}
/**************************************************************************
ETH_TRANSMIT - Transmit a frame
***************************************************************************/
static const char padmap[] = {
0, 3, 2, 1};
int
EtherSend(char *pkt, int len)
{
int pad;
int status;
#ifdef EDEBUG
printf("{l=%d}", len);
#endif
pad = padmap[len & 3];
/*
* The 3c509 automatically pads short packets to minimum ethernet length,
* but we drop packets that are too large. Perhaps we should truncate
* them instead?
*/
if (len + pad > ETHER_MAX_LEN) {
return -1;
}
/* drop acknowledgements */
while ((status = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE ) {
if (status & (TXS_UNDERRUN | TXS_MAX_COLLISION |
TXS_STATUS_OVERFLOW)) {
outw(BASE + EP_COMMAND, TX_RESET);
outw(BASE + EP_COMMAND, TX_ENABLE);
}
outb(BASE + EP_W1_TX_STATUS, 0x0);
}
while (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
/* no room in FIFO */
continue;
}
outw(BASE + EP_W1_TX_PIO_WR_1, len);
outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
/* write packet */
outsw(BASE + EP_W1_TX_PIO_WR_1, pkt, len / 2);
if (len & 1)
outb(BASE + EP_W1_TX_PIO_WR_1, *(pkt + len - 1));
while (pad--)
outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */
/* timeout after sending */
delay(1000);
return len;
}
/**************************************************************************
ETH_POLL - Wait for a frame
***************************************************************************/
int
EtherReceive(char *pkt, int maxlen)
{
/* common variables */
int len;
/* variables for 3C509 */
short status, cst;
register short rx_fifo;
cst = inw(BASE + EP_STATUS);
#ifdef EDEBUG
if (cst & 0x1FFF)
printf("-%x-",cst);
#endif
if ((cst & (S_RX_COMPLETE|S_RX_EARLY)) == 0) {
/* acknowledge everything */
outw(BASE + EP_COMMAND, ACK_INTR| (cst & S_5_INTS));
outw(BASE + EP_COMMAND, C_INTR_LATCH);
return 0;
}
status = inw(BASE + EP_W1_RX_STATUS);
#ifdef EDEBUG
printf("*%x*",status);
#endif
if (status & ERR_RX) {
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
return 0;
}
rx_fifo = status & RX_BYTES_MASK;
if (rx_fifo == 0)
return 0;
if (rx_fifo > maxlen)
goto zulang;
/* read packet */
#ifdef EDEBUG
printf("[l=%d",rx_fifo);
#endif
insw(BASE + EP_W1_RX_PIO_RD_1, pkt, rx_fifo / 2);
if (rx_fifo & 1)
pkt[rx_fifo-1] = inb(BASE + EP_W1_RX_PIO_RD_1);
len = rx_fifo;
for (;;) {
status = inw(BASE + EP_W1_RX_STATUS);
#ifdef EDEBUG
printf("*%x*",status);
#endif
rx_fifo = status & RX_BYTES_MASK;
if (rx_fifo > 0) {
if ((len + rx_fifo) > maxlen)
goto zulang;
insw(BASE + EP_W1_RX_PIO_RD_1, pkt + len, rx_fifo / 2);
if (rx_fifo & 1)
pkt[len + rx_fifo-1] = inb(BASE + EP_W1_RX_PIO_RD_1);
len += rx_fifo;
#ifdef EDEBUG
printf("+%d",rx_fifo);
#endif
}
if ((status & RX_INCOMPLETE) == 0) {
#ifdef EDEBUG
printf("=%d",len);
#endif
break;
}
delay(1000);
}
/* acknowledge reception of packet */
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
continue;
return len;
zulang:
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
continue;
return 0;
}
/*************************************************************************
3Com 509 - specific routines
**************************************************************************/
static int
eeprom_rdy(void)
{
int i;
for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);
if (i >= MAX_EEPROMBUSY) {
printf("3c509: eeprom failed to come ready.\r\n");
return 0;
}
return 1;
}
/*
* get_e: gets a 16 bits word from the EEPROM. we must have set the window
* before
*/
int
ep_get_e(int offset)
{
if (!eeprom_rdy())
return 0xffff;
outw(IS_BASE + EP_W0_EEPROM_COMMAND, EEPROM_CMD_RD | offset);
if (!eeprom_rdy())
return 0xffff;
return inw(IS_BASE + EP_W0_EEPROM_DATA);
}

View file

@ -0,0 +1,39 @@
/* $NetBSD: etherdrv.h,v 1.9 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
int EtherInit(unsigned char *);
int EtherSend(char *, int);
int EtherReceive(char *, int);
void EtherStop(void);
extern unsigned ether_medium;
#define ETHERMEDIUM_BNC 0
#define ETHERMEDIUM_UTP 1
#define ETHERMEDIUM_AUI 2
#define ETHERMEDIUM_MII 3
#define ETHERMEDIUM_100TX 4

View file

@ -0,0 +1,492 @@
/* $NetBSD: i82557.c,v 1.11 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1998, 1999
* Matthias Drochner. All rights reserved.
* Copyright (c) 1995, David Greenman
* 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 unmodified, 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.
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <dev/ic/i82557reg.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include <pcivar.h>
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
#include <lib/libkern/libkern.h>
#include <bootinfo.h>
#endif
#include "etherdrv.h"
#define RECVBUF_SIZE 1600 /* struct fxp_rfa + packet */
#ifdef _STANDALONE
static pcihdl_t mytag;
static char recvbuf[RECVBUF_SIZE];
#define RECVBUF_PHYS vtophys(recvbuf)
#define RECVBUF_VIRT ((void *)recvbuf)
static union _sndbuf {
struct fxp_cb_config cbp;
struct fxp_cb_ias cb_ias;
struct fxp_cb_tx txp;
} sndbuf;
#define SNDBUF_PHYS vtophys(&sndbuf)
#define SNDBUF_VIRT ((void *)&sndbuf)
#else /* !standalone, userspace testing environment */
#define PCI_MODE1_ENABLE 0x80000000UL
static pcihdl_t mytag = PCI_MODE1_ENABLE | (PCIDEVNO << 11);
extern void *mapmem(int, int);
void *dmamem; /* virtual */
#define RECVBUF_PHYS DMABASE
#define RECVBUF_VIRT dmamem
#define SNDBUF_PHYS (DMABASE + RECVBUF_SIZE)
#define SNDBUF_VIRT ((void *)(((char *)dmamem) + RECVBUF_SIZE))
#endif /* _STANDALONE */
static void fxp_read_eeprom(uint16_t *, int, int);
static inline void fxp_scb_wait(void);
#ifdef DEBUG
static void fxp_checkintr(char *);
#else
#define fxp_checkintr(x)
#endif
static void fxp_startreceiver(void);
/*
* Template for default configuration parameters.
* See struct fxp_cb_config for the bit definitions.
*/
static uint8_t fxp_cb_config_template[] = {
0x0, 0x0, /* cb_status */
0x80, 0x2, /* cb_command */
0xff, 0xff, 0xff, 0xff, /* link_addr */
0x16, /* 0 */
0x8, /* 1 */
0x0, /* 2 */
0x0, /* 3 */
0x0, /* 4 */
0x80, /* 5 */
0xb2, /* 6 */
0x3, /* 7 */
0x1, /* 8 */
0x0, /* 9 */
0x26, /* 10 */
0x0, /* 11 */
0x60, /* 12 */
0x0, /* 13 */
0xf2, /* 14 */
0x48, /* 15 */
0x0, /* 16 */
0x40, /* 17 */
0xf3, /* 18 */
0x0, /* 19 */
0x3f, /* 20 */
0x5 /* 21 */
};
static int tx_threshold = 64; /* x8, max 192 */
#define CSR_READ_1(reg) inb(iobase + (reg))
#define CSR_READ_2(reg) inw(iobase + (reg))
#define CSR_WRITE_1(reg, val) outb(iobase + (reg), val)
#define CSR_WRITE_2(reg, val) outw(iobase + (reg), val)
#define CSR_WRITE_4(reg, val) outl(iobase + (reg), val)
#define DELAY(n) delay(n)
static int iobase;
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
static struct btinfo_netif bi_netif;
#endif
/*
* Wait for the previous command to be accepted (but not necessarily
* completed).
*/
static inline void
fxp_scb_wait(void)
{
int i = 10000;
while (CSR_READ_1(FXP_CSR_SCB_COMMAND) && --i)
DELAY(1);
if (i == 0)
printf("fxp: WARNING: SCB timed out!\n");
}
#ifdef DEBUG
static void
fxp_checkintr(char *msg)
{
uint8_t statack;
int i = 10000;
do {
statack = CSR_READ_1(FXP_CSR_SCB_STATACK);
} while ((statack == 0) && (--i > 0));
if (statack != 0) {
CSR_WRITE_1(FXP_CSR_SCB_STATACK, statack);
printf("%s: ack'd irq %x, i=%d\n", msg, statack, i);
}
}
#endif
int
EtherInit(unsigned char *myadr)
{
#ifndef _STANDALONE
uint32_t id;
#endif
volatile struct fxp_cb_config *cbp;
volatile struct fxp_cb_ias *cb_ias;
int i;
if (pcicheck()) {
printf("pcicheck failed\n");
return 0;
}
#ifdef _STANDALONE
if (pcifinddev(0x8086, 0x1229, &mytag)) {
printf("no fxp\n");
return 0;
}
#else
pcicfgread(&mytag, 0, &id);
if (id != 0x12298086) {
printf("no fxp\n");
return 0;
}
#endif
pcicfgread(&mytag, FXP_PCI_IOBA, &iobase);
iobase &= ~3;
#ifndef _STANDALONE
dmamem = mapmem(DMABASE, DMASIZE);
if (!dmamem)
return 0;
#endif
fxp_read_eeprom((void *)myadr, 0, 3);
/*
* Initialize base of CBL and RFA memory. Loading with zero
* sets it up for regular linear addressing.
*/
CSR_WRITE_4(FXP_CSR_SCB_GENERAL, 0);
CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_BASE);
fxp_scb_wait();
CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_BASE);
cbp = SNDBUF_VIRT;
/*
* This memcpy is kind of disgusting, but there are a bunch of must be
* zero and must be one bits in this structure and this is the easiest
* way to initialize them all to proper values.
*/
memcpy((void *)cbp, fxp_cb_config_template,
sizeof(fxp_cb_config_template));
#define prm 0
#define phy_10Mbps_only 0
#define all_mcasts 0
cbp->cb_status = 0;
cbp->cb_command = FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL;
cbp->link_addr = -1; /* (no) next command */
cbp->byte_count = 22; /* (22) bytes to config */
cbp->rx_fifo_limit = 8; /* rx fifo threshold (32 bytes) */
cbp->tx_fifo_limit = 0; /* tx fifo threshold (0 bytes) */
cbp->adaptive_ifs = 0; /* (no) adaptive interframe spacing */
cbp->rx_dma_bytecount = 0; /* (no) rx DMA max */
cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */
cbp->dma_mbce = 0; /* (disable) dma max counters */
cbp->late_scb = 0; /* (don't) defer SCB update */
cbp->tno_int_or_tco_en = 0; /* (disable) tx not okay interrupt */
cbp->ci_int = 0; /* interrupt on CU not active */
cbp->save_bf = prm; /* save bad frames */
cbp->disc_short_rx = !prm; /* discard short packets */
cbp->underrun_retry = 1; /* retry mode (1) on DMA underrun */
cbp->mediatype = !phy_10Mbps_only; /* interface mode */
cbp->nsai = 1; /* (don't) disable source addr insert */
cbp->preamble_length = 2; /* (7 byte) preamble */
cbp->loopback = 0; /* (don't) loopback */
cbp->linear_priority = 0; /* (normal CSMA/CD operation) */
cbp->linear_pri_mode = 0; /* (wait after xmit only) */
cbp->interfrm_spacing = 6; /* (96 bits of) interframe spacing */
cbp->promiscuous = prm; /* promiscuous mode */
cbp->bcast_disable = 0; /* (don't) disable broadcasts */
cbp->crscdt = 0; /* (CRS only) */
cbp->stripping = !prm; /* truncate rx packet to byte count */
cbp->padding = 1; /* (do) pad short tx packets */
cbp->rcv_crc_xfer = 0; /* (don't) xfer CRC to host */
cbp->force_fdx = 0; /* (don't) force full duplex */
cbp->fdx_pin_en = 1; /* (enable) FDX# pin */
cbp->multi_ia = 0; /* (don't) accept multiple IAs */
cbp->mc_all = all_mcasts;/* accept all multicasts */
#undef prm
#undef phy_10Mbps_only
#undef all_mcasts
/*
* Start the config command/DMA.
*/
fxp_scb_wait();
CSR_WRITE_4(FXP_CSR_SCB_GENERAL, SNDBUF_PHYS);
CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
/* ...and wait for it to complete. */
i = 10000;
while (!(cbp->cb_status & FXP_CB_STATUS_C) && (--i > 0))
DELAY(1);
if (i == 0)
printf("config timeout");
fxp_checkintr("config");
cb_ias = SNDBUF_VIRT;
/*
* Now initialize the station address. Temporarily use the TxCB
* memory area like we did above for the config CB.
*/
cb_ias->cb_status = 0;
cb_ias->cb_command = FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL;
cb_ias->link_addr = -1;
memcpy((void *)cb_ias->macaddr, myadr, 6);
/*
* Start the IAS (Individual Address Setup) command/DMA.
*/
fxp_scb_wait();
/* address is still there */
CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
/* ...and wait for it to complete. */
i = 10000;
while (!(cb_ias->cb_status & FXP_CB_STATUS_C) && (--i > 0))
DELAY(1);
if (i == 0)
printf("ias timeout");
fxp_checkintr("ias");
fxp_startreceiver();
#if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
strncpy(bi_netif.ifname, "fxp", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_PCI;
bi_netif.addr.tag = mytag;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
#endif
return 1;
}
void
EtherStop(void)
{
/*
* Issue software reset
*/
CSR_WRITE_4(FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
DELAY(10);
}
int
EtherSend(char *pkt, int len)
{
volatile struct fxp_cb_tx *txp;
#ifdef _STANDALONE
static volatile struct fxp_tbd tbd;
#endif
volatile struct fxp_tbd *tbdp;
int i;
txp = SNDBUF_VIRT;
#ifdef _STANDALONE
tbdp = &tbd;
txp->tbd_array_addr = vtophys((void *)&tbd);
tbdp->tb_addr = vtophys(pkt);
#else
/* XXX assuming we send at max 400 bytes */
tbdp = (struct fxp_tbd *)(SNDBUF_VIRT + 440);
txp->tbd_array_addr = SNDBUF_PHYS + 440;
memcpy(SNDBUF_VIRT + 400, pkt, len);
tbdp->tb_addr = SNDBUF_PHYS + 400;
#endif
tbdp->tb_size = len;
txp->tbd_number = 1;
txp->cb_status = 0;
txp->cb_command =
FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF | FXP_CB_COMMAND_EL;
txp->tx_threshold = tx_threshold;
txp->link_addr = -1;
txp->byte_count = 0;
fxp_scb_wait();
CSR_WRITE_4(FXP_CSR_SCB_GENERAL, SNDBUF_PHYS);
CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
/* ...and wait for it to complete. */
i = 10000;
while (!(txp->cb_status & FXP_CB_STATUS_C) && (--i > 0))
DELAY(1);
if (i == 0)
printf("send timeout");
fxp_checkintr("send");
return len;
}
static void
fxp_startreceiver(void)
{
volatile struct fxp_rfa *rfa;
uint32_t v;
rfa = RECVBUF_VIRT;
rfa->size = RECVBUF_SIZE - sizeof(struct fxp_rfa);
rfa->rfa_status = 0;
rfa->rfa_control = FXP_RFA_CONTROL_S;
rfa->actual_size = 0;
v = RECVBUF_PHYS; /* close the "ring" */
memcpy((void *)&rfa->link_addr, &v, sizeof(v));
v = -1;
memcpy((void *)&rfa->rbd_addr, &v, sizeof(v));
fxp_scb_wait();
CSR_WRITE_4(FXP_CSR_SCB_GENERAL, RECVBUF_PHYS);
CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_START);
}
int
EtherReceive(char *pkt, int maxlen)
{
uint8_t ruscus;
volatile struct fxp_rfa *rfa;
int len = 0;
ruscus = CSR_READ_1(FXP_CSR_SCB_RUSCUS);
if (((ruscus >> 2) & 0x0f) == FXP_SCB_RUS_READY)
return 0;
if (((ruscus >> 2) & 0x0f) != FXP_SCB_RUS_SUSPENDED) {
printf("rcv: ruscus=%x\n", ruscus);
return 0;
}
rfa = RECVBUF_VIRT;
if (rfa->rfa_status & FXP_RFA_STATUS_C) {
len = rfa->actual_size & 0x7ff;
if (len <= maxlen) {
memcpy(pkt, (char *) rfa + RFA_SIZE, maxlen);
#if 0
printf("rfa status=%x, len=%x\n",
rfa->rfa_status, len);
#endif
} else
len = 0;
}
fxp_scb_wait();
CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_RESUME);
return len;
}
/*
* Read from the serial EEPROM. Basically, you manually shift in
* the read opcode (one bit at a time) and then shift in the address,
* and then you shift out the data (all of this one bit at a time).
* The word size is 16 bits, so you have to provide the address for
* every 16 bits of data.
*/
static void
fxp_read_eeprom(uint16_t *data, int offset, int words)
{
uint16_t reg;
int i, x;
for (i = 0; i < words; i++) {
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
/*
* Shift in read opcode.
*/
for (x = 3; x > 0; x--) {
if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {
reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
} else {
reg = FXP_EEPROM_EECS;
}
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg);
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL,
reg | FXP_EEPROM_EESK);
DELAY(1);
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg);
DELAY(1);
}
/*
* Shift in address.
*/
for (x = 6; x > 0; x--) {
if ((i + offset) & (1 << (x - 1))) {
reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
} else {
reg = FXP_EEPROM_EECS;
}
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg);
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL,
reg | FXP_EEPROM_EESK);
DELAY(1);
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg);
DELAY(1);
}
reg = FXP_EEPROM_EECS;
data[i] = 0;
/*
* Shift out data.
*/
for (x = 16; x > 0; x--) {
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL,
reg | FXP_EEPROM_EESK);
DELAY(1);
if (CSR_READ_2(FXP_CSR_EEPROMCONTROL) &
FXP_EEPROM_EEDO)
data[i] |= (1 << (x - 1));
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg);
DELAY(1);
}
CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, 0);
DELAY(1);
}
}

View file

@ -0,0 +1,113 @@
/* $NetBSD: lance.h,v 1.2 2008/12/14 18:46:33 christos Exp $ */
/*
* source in this file came from
* the Mach ethernet boot written by Leendert van Doorn.
*/
/* RAP functions as a select for RDP */
#define RDP_CSR0 0
#define RDP_CSR1 1
#define RDP_CSR2 2
#define RDP_CSR3 3
/* contents of csr0 */
#define CSR_ERR 0x8000
#define CSR_BABL 0x4000
#define CSR_CERR 0x2000
#define CSR_MISS 0x1000
#define CSR_MERR 0x0800
#define CSR_RINT 0x0400
#define CSR_TINT 0x0200
#define CSR_IDON 0x0100
#define CSR_INTR 0x0080
#define CSR_INEA 0x0040
#define CSR_RXON 0x0020
#define CSR_TXON 0x0010
#define CSR_TDMD 0x0008
#define CSR_STOP 0x0004
#define CSR_STRT 0x0002
#define CSR_INIT 0x0001
/* csr1 contains low 16 bits of address of Initialization Block */
/* csr2 contains in low byte high 8 bits of address of InitBlock */
/* contents of csr3 */
#define CSR3_BSWP 0x04 /* byte swap (for big endian) */
#define CSR3_ACON 0x02 /* ALE control */
#define CSR3_BCON 0x01 /* byte control */
/*
* The initialization block
*/
typedef struct {
u_short ib_mode; /* modebits, see below */
char ib_padr[6]; /* physical 48bit Ether-address */
u_short ib_ladrf[4]; /* 64bit hashtable for "logical" addresses */
u_short ib_rdralow; /* low 16 bits of Receiver Descr. Ring addr */
u_char ib_rdrahigh; /* high 8 bits of Receiver Descr. Ring addr */
u_char ib_rlen; /* upper 3 bits are 2log Rec. Ring Length */
u_short ib_tdralow; /* low 16 bits of Transm. Descr. Ring addr */
u_char ib_tdrahigh; /* high 8 bits of Transm. Descr. Ring addr */
u_char ib_tlen; /* upper 3 bits are 2log Transm. Ring Length */
} initblock_t;
/* bits in mode */
#define IB_PROM 0x8000
#define IB_INTL 0x0040
#define IB_DRTY 0x0020
#define IB_COLL 0x0010
#define IB_DTCR 0x0008
#define IB_LOOP 0x0004
#define IB_DTX 0x0002
#define IB_DRX 0x0001
/*
* A receive message descriptor entry
*/
typedef struct {
u_short rmd_ladr; /* low 16 bits of bufaddr */
char rmd_hadr; /* high 8 bits of bufaddr */
char rmd_flags; /* see below */
short rmd_bcnt; /* two's complement of buffer byte count */
u_short rmd_mcnt; /* message byte count */
} rmde_t;
/* bits in flags */
#define RMD_OWN 0x80
#define RMD_ERR 0x40
#define RMD_FRAM 0x20
#define RMD_OFLO 0x10
#define RMD_CRC 0x08
#define RMD_BUFF 0x04
#define RMD_STP 0x02
#define RMD_ENP 0x01
/*
* A transmit message descriptor entry
*/
typedef struct {
u_short tmd_ladr; /* low 16 bits of bufaddr */
u_char tmd_hadr; /* high 8 bits of bufaddr */
u_char tmd_flags; /* see below */
short tmd_bcnt; /* two's complement of buffer byte count */
u_short tmd_err; /* more error bits + TDR */
} tmde_t;
/* bits in flags */
#define TMD_OWN 0x80
#define TMD_ERR 0x40
#define TMD_MORE 0x10
#define TMD_ONE 0x08
#define TMD_DEF 0x04
#define TMD_STP 0x02
#define TMD_ENP 0x01
/* bits in tmd_err */
#define TMDE_BUFF 0x8000
#define TMDE_UFLO 0x4000
#define TMDE_LCOL 0x1000
#define TMDE_LCAR 0x0800
#define TMDE_RTRY 0x0400
#define TMDE_TDR 0x003F /* mask for TDR */

View file

@ -0,0 +1,274 @@
/* $NetBSD: ne.c,v 1.7 2008/12/14 18:46:33 christos Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
* adapters.
*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
*
* Copyright (C) 1993, David Greenman. This software may be used, modified,
* copied, distributed, and sold, in both source and binary form provided that
* the above copyright and these terms are retained. Under no circumstances is
* the author responsible for the proper functioning of this software, nor does
* the author assume any responsibility for damages incurred with its use.
*/
/*
* this code is mainly obtained from /sys/dev/ic/ne2000.c .
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#ifdef _STANDALONE
#include <lib/libkern/libkern.h>
#include <bootinfo.h>
#endif
#include "etherdrv.h"
#include <dev/ic/dp8390reg.h>
#include <dev/ic/ne2000reg.h>
#include "dp8390.h"
#include "ne.h"
#ifndef BASEREG
#define BASEREG 0x300
#endif
#define NE_BASEREG BASEREG
#define NE_ASIC_BASEREG (NE_BASEREG+NE2000_ASIC_OFFSET)
#define NIC_PORT(x) (NE_BASEREG + (x))
#define NIC_INB(x) inb(NIC_PORT(x))
#define NIC_OUTB(x, b) outb(NIC_PORT(x), (b))
#define NE_16BIT
#define DELAY(x) delay(x)
#define ASIC_PORT(x) (NE_ASIC_BASEREG + (x))
#define ASIC_INB(x) inb(ASIC_PORT(x))
#define ASIC_INW(x) inw(ASIC_PORT(x))
#define ASIC_OUTB(x, b) outb(ASIC_PORT(x), (b))
#define ASIC_OUTW(x, b) outw(ASIC_PORT(x), (b))
u_char eth_myaddr[6];
#ifdef _STANDALONE
static struct btinfo_netif bi_netif;
#endif
int
EtherInit(unsigned char *myadr)
{
uint8_t tmp;
int i;
printf("ne: trying iobase=0x%x\n", NE_BASEREG);
dp8390_iobase = NE_BASEREG;
dp8390_membase = dp8390_memsize = 8192*2;
dp8390_cr_proto = ED_CR_RD2;
dp8390_dcr_reg = ED_DCR_FT1 | ED_DCR_LS
#ifdef NE_16BIT
| ED_DCR_WTS
#endif
;
/* reset */
tmp = ASIC_INB(NE2000_ASIC_RESET);
DELAY(10000);
ASIC_OUTB(NE2000_ASIC_RESET, tmp);
DELAY(5000);
NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
DELAY(5000);
tmp = NIC_INB(ED_P0_CR);
if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
(ED_CR_RD2 | ED_CR_STP)) {
goto out;
}
tmp = NIC_INB(ED_P0_ISR);
if ((tmp & ED_ISR_RST) != ED_ISR_RST) {
goto out;
}
NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
for (i = 0; i < 100; i++) {
if ((NIC_INB(ED_P0_ISR) & ED_ISR_RST) ==
ED_ISR_RST) {
/* Ack the reset bit. */
NIC_OUTB(ED_P0_ISR, ED_ISR_RST);
break;
}
DELAY(100);
}
printf("ne: found\n");
/*
* This prevents packets from being stored in the NIC memory when
* the readmem routine turns on the start bit in the CR.
*/
NIC_OUTB(ED_P0_RCR, ED_RCR_MON);
/* Temporarily initialize DCR for byte operations. */
NIC_OUTB(ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
NIC_OUTB(ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT);
NIC_OUTB(ED_P0_PSTOP, 16384 >> ED_PAGE_SHIFT);
#ifdef HWADDR
for (i = 0; i < 6; i++)
myadr[i] = eth_myaddr[i] = HWADDR[i];
#else
{
uint8_t romdata[16];
ne2000_readmem(0, romdata, 16);
for (i = 0; i < 6; i++)
myadr[i] = eth_myaddr[i] = romdata[i*2];
}
#endif
if (dp8390_config())
goto out;
#ifdef _STANDALONE
strncpy(bi_netif.ifname, "ne", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_ISA;
bi_netif.addr.iobase = NE_BASEREG;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
#endif
return 1;
out:
return 0;
}
void
EtherStop(void) {
uint8_t tmp;
dp8390_stop();
tmp = ASIC_INB(NE2000_ASIC_RESET);
DELAY(10000);
ASIC_OUTB(NE2000_ASIC_RESET, tmp);
DELAY(5000);
NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
DELAY(5000);
}
void
ne2000_writemem(uint8_t *src, int dst, size_t len)
{
size_t i;
int maxwait = 100; /* about 120us */
/* Select page 0 registers. */
NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
/* Reset remote DMA complete flag. */
NIC_OUTB(ED_P0_ISR, ED_ISR_RDC);
/* Set up DMA byte count. */
NIC_OUTB(ED_P0_RBCR0, len);
NIC_OUTB(ED_P0_RBCR1, len >> 8);
/* Set up destination address in NIC mem. */
NIC_OUTB(ED_P0_RSAR0, dst);
NIC_OUTB(ED_P0_RSAR1, dst >> 8);
/* Set remote DMA write. */
NIC_OUTB(ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
#ifdef NE_16BIT
for (i = 0; i < len; i += 2, src += 2)
ASIC_OUTW(NE2000_ASIC_DATA, *(uint16_t *)src);
#else
for (i = 0; i < len; i++)
ASIC_OUTB(NE2000_ASIC_DATA, *src++);
#endif
/*
* Wait for remote DMA to complete. This is necessary because on the
* transmit side, data is handled internally by the NIC in bursts, and
* we can't start another remote DMA until this one completes. Not
* waiting causes really bad things to happen - like the NIC wedging
* the bus.
*/
while (((NIC_INB(ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait)
DELAY(1);
if (maxwait == 0)
printf("ne2000_writemem: failed to complete\n");
}
void
ne2000_readmem(int src, uint8_t *dst, size_t amount)
{
size_t i;
/* Select page 0 registers. */
NIC_OUTB(ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
/* Round up to a word. */
if (amount & 1)
++amount;
/* Set up DMA byte count. */
NIC_OUTB(ED_P0_RBCR0, amount);
NIC_OUTB(ED_P0_RBCR1, amount >> 8);
/* Set up source address in NIC mem. */
NIC_OUTB(ED_P0_RSAR0, src);
NIC_OUTB(ED_P0_RSAR1, src >> 8);
NIC_OUTB(ED_P0_CR, ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA);
#ifdef NE_16BIT
for (i = 0; i < amount; i += 2, dst += 2)
*(uint16_t *)dst = ASIC_INW(NE2000_ASIC_DATA);
#else
for (i = 0; i < amount; i++)
*dst++ = ASIC_INB(NE2000_ASIC_DATA);
#endif
}

View file

@ -0,0 +1,4 @@
/* $NetBSD: ne.h,v 1.3 2008/12/14 18:46:33 christos Exp $ */
void ne2000_readmem(int, uint8_t *, size_t);
void ne2000_writemem(uint8_t *, int, size_t);

View file

@ -0,0 +1,165 @@
/* $NetBSD: netif_small.c,v 1.12 2009/10/21 23:12:09 snj Exp $ */
/* minimal netif - for boot ROMs we don't have to select between
several interfaces, and we have to save space
hacked from netbsd:sys/arch/mvme68k/stand/libsa/netif.c
*/
/*
* Copyright (c) 1995 Gordon W. Ross
* 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/socket.h>
#ifdef _STANDALONE
#include <lib/libkern/libkern.h>
#else
#include <string.h>
#endif
#include <net/if.h>
#include <net/if_ether.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <lib/libsa/stand.h>
#include <lib/libsa/net.h>
#include "netif_small.h"
#include "etherdrv.h"
#ifdef NETIF_DEBUG
int netif_debug = 1;
#endif
/* we allow for one socket only */
static struct iodesc iosocket;
struct iodesc *
socktodesc(int sock)
{
if (sock != 0) {
return NULL;
}
return &iosocket;
}
int
netif_open(void)
{
struct iodesc *io;
io = &iosocket;
if (io->io_netif) {
#ifdef NETIF_DEBUG
printf("netif_open: device busy\n");
#endif
return -1;
}
memset(io, 0, sizeof(*io));
if (!EtherInit(io->myea)) {
printf("EtherInit failed\n");
return -1;
}
io->io_netif = (void*)1; /* mark busy */
return 0;
}
void
netif_close(int fd)
{
struct iodesc *io;
if (fd != 0) {
return;
}
io = &iosocket;
if (io->io_netif) {
EtherStop();
io->io_netif = NULL;
}
}
/*
* Send a packet. The ether header is already there.
* Return the length sent (or -1 on error).
*/
int
netif_put(struct iodesc *desc, void *pkt, size_t len)
{
#ifdef NETIF_DEBUG
if (netif_debug) {
struct ether_header *eh;
printf("netif_put: desc=%p pkt=%p len=%d\n",
desc, pkt, len);
eh = pkt;
printf("dst: %s ", ether_sprintf(eh->ether_dhost));
printf("src: %s ", ether_sprintf(eh->ether_shost));
printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
}
#endif
return EtherSend(pkt, len);
}
/*
* Receive a packet, including the ether header.
* Return the total length received (or -1 on error).
*/
int
netif_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timo)
{
int len;
satime_t t;
#ifdef NETIF_DEBUG
if (netif_debug)
printf("netif_get: pkt=%p, maxlen=%d, tmo=%d\n",
pkt, maxlen, timo);
#endif
t = getsecs();
len = 0;
while (((getsecs() - t) < timo) && !len) {
len = EtherReceive(pkt, maxlen);
}
#ifdef NETIF_DEBUG
if (netif_debug) {
struct ether_header *eh = pkt;
printf("dst: %s ", ether_sprintf(eh->ether_dhost));
printf("src: %s ", ether_sprintf(eh->ether_shost));
printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
}
#endif
return len;
}

View file

@ -0,0 +1,35 @@
/* $NetBSD: netif_small.h,v 1.5 2009/10/21 23:12:09 snj Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
* 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <lib/libsa/iodesc.h>
/* minimal netif - for boot ROMs we don't have to select between
several interfaces, and we have to save space */
int netif_open(void);
void netif_close(int);

View file

@ -0,0 +1,89 @@
/* $NetBSD: pcnet_isapnp.c,v 1.8 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <libi386.h>
#include <isapnpvar.h>
#include <isadmavar.h>
#include <bootinfo.h>
#include "etherdrv.h"
#include "lance.h"
#ifndef ISAPNPID
#define ISAPNPID 0x516e0010 /* TKN0010 */
#endif
int lance_rap, lance_rdp;
u_char eth_myaddr[6];
extern void am7990_init(void);
extern void am7990_stop(void);
static struct btinfo_netif bi_netif;
int
EtherInit(unsigned char *myadr)
{
int iobase, dmachan, i;
if (isapnp_finddev(ISAPNPID, &iobase, &dmachan)) {
printf("cannot find PCNET\n");
return 0;
}
printf("printf using PCNET @ %x\n", iobase);
lance_rap = iobase + 0x12;
lance_rdp = iobase + 0x10;
/* make sure it's stopped */
am7990_stop();
for (i = 0; i < 6; i++)
myadr[i] = eth_myaddr[i] = inb(iobase + i);
isa_dmacascade(dmachan);
am7990_init();
strncpy(bi_netif.ifname, "le", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_ISA;
bi_netif.addr.iobase = iobase;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
return 1;
}

View file

@ -0,0 +1,99 @@
/* $NetBSD: pcnet_pci.c,v 1.8 2008/12/14 18:46:33 christos Exp $ */
/*
* Copyright (c) 1996
* Matthias Drochner. 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 ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libkern/libkern.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include <pcivar.h>
#include <bootinfo.h>
#include "etherdrv.h"
#include "lance.h"
int lance_rap, lance_rdp;
static pcihdl_t hdl;
u_char eth_myaddr[6];
extern void am7990_init(void);
extern void am7990_stop(void);
static struct btinfo_netif bi_netif;
int
EtherInit(unsigned char *myadr)
{
int iobase, pcicsr, i;
if (pcicheck() == -1) {
printf("cannot access PCI\n");
return 0;
}
if (pcifinddev(0x1022, 0x2000, &hdl)) {
printf("cannot find PCNET\n");
return 0;
}
if (pcicfgread(&hdl, 0x10, &iobase) || !(iobase & 1)) {
printf("cannot map IO space\n");
return 0;
}
iobase &= 0xfffffffc;
lance_rap = iobase + 0x12;
lance_rdp = iobase + 0x10;
/* make sure it's stopped */
am7990_stop();
/* enable bus mastering in PCI command register */
if (pcicfgread(&hdl, 0x04, &pcicsr)
|| pcicfgwrite(&hdl, 0x04, pcicsr | 4)) {
printf("cannot enable DMA\n");
return 0;
}
for (i = 0; i < 6; i++)
myadr[i] = eth_myaddr[i] = inb(iobase + i);
am7990_init();
strncpy(bi_netif.ifname, "le", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_PCI;
bi_netif.addr.tag = hdl;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
return 1;
}

View file

@ -0,0 +1,323 @@
/* $NetBSD: wd80x3.c,v 1.10 2008/12/14 18:46:33 christos Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
* adapters.
*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
*
* Copyright (C) 1993, David Greenman. This software may be used, modified,
* copied, distributed, and sold, in both source and binary form provided that
* the above copyright and these terms are retained. Under no circumstances is
* the author responsible for the proper functioning of this software, nor does
* the author assume any responsibility for damages incurred with its use.
*/
/*
* Device driver for the Western Digital/SMC 8003 and 8013 series,
* and the SMC Elite Ultra (8216).
*/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#ifdef _STANDALONE
#include <lib/libkern/libkern.h>
#include <bootinfo.h>
#endif
#include "etherdrv.h"
#include <dev/ic/dp8390reg.h>
#include "dp8390.h"
#include <dev/ic/wereg.h>
#ifndef BASEREG
#define BASEREG 0x240
#define BASEMEM 0xd0000
#endif
#define WD_BASEREG BASEREG
#define WD_BASEMEM BASEMEM
#ifndef _STANDALONE
extern int mapio(void);
#endif
u_char eth_myaddr[6];
static uint8_t we_type;
static int we_is16bit;
#ifdef _STANDALONE
static struct btinfo_netif bi_netif;
#endif
const char *
we_params(void)
{
const char *typestr;
dp8390_memsize = 8192;
we_type = inb(WD_BASEREG + WE_CARD_ID);
switch (we_type) {
#ifdef SUPPORT_WD80X3
case WE_TYPE_WD8003S:
typestr = "WD8003S";
break;
case WE_TYPE_WD8003E:
typestr = "WD8003E";
break;
case WE_TYPE_WD8003EB:
typestr = "WD8003EB";
break;
case WE_TYPE_WD8003W:
typestr = "WD8003W";
break;
case WE_TYPE_WD8013EBT:
typestr = "WD8013EBT";
dp8390_memsize = 16384;
we_is16bit = 1;
break;
case WE_TYPE_WD8013W:
typestr = "WD8013W";
dp8390_memsize = 16384;
we_is16bit = 1;
break;
case WE_TYPE_WD8013EP: /* also WD8003EP */
if (inb(WD_BASEREG + WE_ICR) & WE_ICR_16BIT) {
we_is16bit = 1;
dp8390_memsize = 16384;
typestr = "WD8013EP";
} else
typestr = "WD8003EP";
break;
case WE_TYPE_WD8013WC:
typestr = "WD8013WC";
dp8390_memsize = 16384;
we_is16bit = 1;
break;
case WE_TYPE_WD8013EBP:
typestr = "WD8013EBP";
dp8390_memsize = 16384;
we_is16bit = 1;
break;
case WE_TYPE_WD8013EPC:
typestr = "WD8013EPC";
dp8390_memsize = 16384;
we_is16bit = 1;
break;
#endif
#ifdef SUPPORT_SMC_ULTRA
case WE_TYPE_SMC8216C:
case WE_TYPE_SMC8216T:
{
uint8_t hwr;
typestr = (we_type == WE_TYPE_SMC8216C) ?
"SMC8216/SMC8216C" : "SMC8216T";
hwr = inb(WD_BASEREG + WE790_HWR);
outb(WD_BASEREG + WE790_HWR, hwr | WE790_HWR_SWH);
switch (inb(WD_BASEREG + WE790_RAR) & WE790_RAR_SZ64) {
case WE790_RAR_SZ64:
dp8390_memsize = 65536;
break;
case WE790_RAR_SZ32:
dp8390_memsize = 32768;
break;
case WE790_RAR_SZ16:
dp8390_memsize = 16384;
break;
case WE790_RAR_SZ8:
/* 8216 has 16K shared mem -- 8416 has 8K */
typestr = (we_type == WE_TYPE_SMC8216C) ?
"SMC8416C/SMC8416BT" : "SMC8416T";
dp8390_memsize = 8192;
break;
}
outb(WD_BASEREG + WE790_HWR, hwr);
we_is16bit = 1;
#ifdef SUPPORT_WD80X3
dp8390_is790 = 1;
#endif
break;
}
#endif
default:
/* Not one we recognize. */
return NULL;
}
/*
* Make some adjustments to initial values depending on what is
* found in the ICR.
*/
if (we_is16bit && (we_type != WE_TYPE_WD8013EBT) &&
(inb(WD_BASEREG + WE_ICR) & WE_ICR_16BIT) == 0) {
we_is16bit = 0;
dp8390_memsize = 8192;
}
#ifdef WE_DEBUG
{
int i;
printf("we_params: type = 0x%x, typestr = %s, is16bit = %d, "
"memsize = %d\n", we_type, typestr, we_is16bit, dp8390_memsize);
for (i = 0; i < 8; i++)
printf(" %d -> 0x%x\n", i,
inb(WD_BASEREG + i));
}
#endif
return typestr;
}
int
EtherInit(unsigned char *myadr)
{
const char *typestr;
uint8_t x;
int i;
uint8_t laar_proto;
uint8_t msr_proto;
dp8390_iobase = WD_BASEREG + WE_NIC_OFFSET;
dp8390_membase = WD_BASEMEM;
#ifndef _STANDALONE
if (mapio()) {
printf("no IO access\n");
return 0;
}
#endif
for (x = 0, i = 0; i < 8; i++)
x += inb(WD_BASEREG + WE_PROM + i);
if (x != WE_ROM_CHECKSUM_TOTAL)
return 0;
/* reset the ethernet card */
outb(WD_BASEREG + WE_MSR, WE_MSR_RST);
delay(100);
outb(WD_BASEREG + WE_MSR, inb(WD_BASEREG + WE_MSR) & ~WE_MSR_RST);
delay(5000);
typestr = we_params();
if (!typestr)
return 0;
printf("Using %s board, port 0x%x, iomem 0x%x, iosiz %d\n",
typestr, WD_BASEREG, WD_BASEMEM, dp8390_memsize);
/* get ethernet address */
for (i = 0; i < 6; i++)
eth_myaddr[i] = myadr[i]= inb(WD_BASEREG + WE_PROM + i);
/*
* Set upper address bits and 8/16 bit access to shared memory.
*/
if (dp8390_is790) {
laar_proto = inb(WD_BASEREG + WE_LAAR) & ~WE_LAAR_M16EN;
outb(WD_BASEREG + WE_LAAR, laar_proto |
(we_is16bit ? WE_LAAR_M16EN : 0));
} else if ((we_type & WE_SOFTCONFIG) ||
(we_type == WE_TYPE_WD8013EBT)) {
laar_proto = (WD_BASEMEM >> 19) & WE_LAAR_ADDRHI;
if (we_is16bit)
laar_proto |= WE_LAAR_L16EN;
outb(WD_BASEREG + WE_LAAR, laar_proto |
(we_is16bit ? WE_LAAR_M16EN : 0));
}
/*
* Set address and enable interface shared memory.
*/
if (dp8390_is790) {
/* XXX MAGIC CONSTANTS XXX */
x = inb(WD_BASEREG + 0x04);
outb(WD_BASEREG + 0x04, x | 0x80);
outb(WD_BASEREG + 0x0b,
((WD_BASEMEM >> 13) & 0x0f) |
((WD_BASEMEM >> 11) & 0x40) |
(inb(WD_BASEREG + 0x0b) & 0xb0));
outb(WD_BASEREG + 0x04, x);
msr_proto = 0x00;
dp8390_cr_proto = 0x00;
} else {
msr_proto = (WD_BASEMEM >> 13) & WE_MSR_ADDR;
dp8390_cr_proto = ED_CR_RD2;
}
outb(WD_BASEREG + WE_MSR, msr_proto | WE_MSR_MENB);
delay(2);
/*
* DCR gets:
*
* FIFO threshold to 8, No auto-init Remote DMA,
* byte order=80x86.
*
* 16-bit cards also get word-wide DMA transfers.
*/
dp8390_dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (we_is16bit ? ED_DCR_WTS : 0);
if (dp8390_config())
return 0;
#ifdef _STANDALONE
strncpy(bi_netif.ifname, "we", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_ISA;
bi_netif.addr.iobase = WD_BASEREG;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
#endif
return 1;
}
/*
* Stop ethernet board
*/
void
EtherStop(void) {
/* stop dp8390, followed by a board reset */
dp8390_stop();
outb(WD_BASEREG + WE_MSR, WE_MSR_RST);
outb(WD_BASEREG + WE_MSR, 0);
}

Some files were not shown because too many files have changed in this diff Show more