Initial import of libsa, libkern, bootxx, boot.
This commit is contained in:
parent
972a791882
commit
58a2b0008e
322 changed files with 51780 additions and 518 deletions
|
@ -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
247
man/man5/boot.cfg.5
Normal 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.
|
1159
man/man8/boot.8
1159
man/man8/boot.8
File diff suppressed because it is too large
Load diff
14
sys/arch/i386/stand/boot/Makefile
Normal file
14
sys/arch/i386/stand/boot/Makefile
Normal 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
|
171
sys/arch/i386/stand/boot/Makefile.boot
Normal file
171
sys/arch/i386/stand/boot/Makefile.boot
Normal 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>
|
149
sys/arch/i386/stand/boot/biosboot.S
Normal file
149
sys/arch/i386/stand/boot/biosboot.S
Normal 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
|
5
sys/arch/i386/stand/boot/biosboot/Makefile
Normal file
5
sys/arch/i386/stand/boot/biosboot/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: Makefile,v 1.3 2005/12/11 12:17:48 christos Exp $
|
||||
|
||||
PROG= boot
|
||||
|
||||
.include <../Makefile.boot>
|
522
sys/arch/i386/stand/boot/boot2.c
Normal file
522
sys/arch/i386/stand/boot/boot2.c
Normal 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");
|
||||
}
|
||||
|
79
sys/arch/i386/stand/boot/conf.c
Normal file
79
sys/arch/i386/stand/boot/conf.c
Normal 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);
|
146
sys/arch/i386/stand/boot/devopen.c
Normal file
146
sys/arch/i386/stand/boot/devopen.c
Normal 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);
|
||||
}
|
5
sys/arch/i386/stand/boot/devopen.h
Normal file
5
sys/arch/i386/stand/boot/devopen.h
Normal 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 *);
|
49
sys/arch/i386/stand/boot/version
Normal file
49
sys/arch/i386/stand/boot/version
Normal 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.
|
21
sys/arch/i386/stand/bootxx/Makefile
Normal file
21
sys/arch/i386/stand/bootxx/Makefile
Normal 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
|
154
sys/arch/i386/stand/bootxx/Makefile.bootxx
Normal file
154
sys/arch/i386/stand/bootxx/Makefile.bootxx
Normal 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>
|
158
sys/arch/i386/stand/bootxx/boot1.c
Normal file
158
sys/arch/i386/stand/bootxx/boot1.c
Normal 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;
|
||||
}
|
136
sys/arch/i386/stand/bootxx/bootxx.S
Normal file
136
sys/arch/i386/stand/bootxx/bootxx.S
Normal 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
|
5
sys/arch/i386/stand/bootxx/bootxx_ext2fs/Makefile
Normal file
5
sys/arch/i386/stand/bootxx/bootxx_ext2fs/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: Makefile,v 1.1 2010/09/11 13:06:37 tsutsui Exp $
|
||||
|
||||
FS=ext2fs
|
||||
|
||||
.include <../Makefile.bootxx>
|
5
sys/arch/i386/stand/bootxx/bootxx_ffsv1/Makefile
Normal file
5
sys/arch/i386/stand/bootxx/bootxx_ffsv1/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:10 dsl Exp $
|
||||
|
||||
FS=ffsv1
|
||||
|
||||
.include <../Makefile.bootxx>
|
5
sys/arch/i386/stand/bootxx/bootxx_ffsv2/Makefile
Normal file
5
sys/arch/i386/stand/bootxx/bootxx_ffsv2/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:10 dsl Exp $
|
||||
|
||||
FS=ffsv2
|
||||
|
||||
.include <../Makefile.bootxx>
|
5
sys/arch/i386/stand/bootxx/bootxx_lfsv1/Makefile
Normal file
5
sys/arch/i386/stand/bootxx/bootxx_lfsv1/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:10 dsl Exp $
|
||||
|
||||
FS=lfsv1
|
||||
|
||||
.include <../Makefile.bootxx>
|
5
sys/arch/i386/stand/bootxx/bootxx_lfsv2/Makefile
Normal file
5
sys/arch/i386/stand/bootxx/bootxx_lfsv2/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: Makefile,v 1.1 2003/04/16 22:26:11 dsl Exp $
|
||||
|
||||
FS=lfsv2
|
||||
|
||||
.include <../Makefile.bootxx>
|
7
sys/arch/i386/stand/bootxx/bootxx_minixfs3/Makefile
Normal file
7
sys/arch/i386/stand/bootxx/bootxx_minixfs3/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
# $NetBSD$
|
||||
|
||||
PROG=bootxx_minixfs3
|
||||
FS=minixfs3
|
||||
CPPFLAGS=-DBOOT_FROM_MINIXFS3 -DTERSE_ERROR
|
||||
|
||||
.include <../Makefile.bootxx>
|
7
sys/arch/i386/stand/bootxx/bootxx_msdos/Makefile
Normal file
7
sys/arch/i386/stand/bootxx/bootxx_msdos/Makefile
Normal 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>
|
7
sys/arch/i386/stand/bootxx/bootxx_ustarfs/Makefile
Normal file
7
sys/arch/i386/stand/bootxx/bootxx_ustarfs/Makefile
Normal 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>
|
19
sys/arch/i386/stand/bootxx/label.S
Normal file
19
sys/arch/i386/stand/bootxx/label.S
Normal 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
|
447
sys/arch/i386/stand/bootxx/pbr.S
Normal file
447
sys/arch/i386/stand/bootxx/pbr.S
Normal 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
|
80
sys/arch/i386/stand/lib/Makefile
Normal file
80
sys/arch/i386/stand/lib/Makefile
Normal 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
|
55
sys/arch/i386/stand/lib/Makefile.inc
Normal file
55
sys/arch/i386/stand/lib/Makefile.inc
Normal 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}
|
297
sys/arch/i386/stand/lib/bios_disk.S
Normal file
297
sys/arch/i386/stand/lib/bios_disk.S
Normal 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
|
214
sys/arch/i386/stand/lib/bios_pci.S
Normal file
214
sys/arch/i386/stand/lib/bios_pci.S
Normal 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
|
78
sys/arch/i386/stand/lib/biosdelay.S
Normal file
78
sys/arch/i386/stand/lib/biosdelay.S
Normal 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
|
808
sys/arch/i386/stand/lib/biosdisk.c
Normal file
808
sys/arch/i386/stand/lib/biosdisk.c
Normal 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;
|
||||
}
|
32
sys/arch/i386/stand/lib/biosdisk.h
Normal file
32
sys/arch/i386/stand/lib/biosdisk.h
Normal 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);
|
319
sys/arch/i386/stand/lib/biosdisk_ll.c
Normal file
319
sys/arch/i386/stand/lib/biosdisk_ll.c
Normal 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;
|
||||
}
|
126
sys/arch/i386/stand/lib/biosdisk_ll.h
Normal file
126
sys/arch/i386/stand/lib/biosdisk_ll.h
Normal 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);
|
58
sys/arch/i386/stand/lib/biosgetrtc.S
Normal file
58
sys/arch/i386/stand/lib/biosgetrtc.S
Normal 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
|
54
sys/arch/i386/stand/lib/biosgetsystime.S
Normal file
54
sys/arch/i386/stand/lib/biosgetsystime.S
Normal 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
|
117
sys/arch/i386/stand/lib/biosmca.S
Normal file
117
sys/arch/i386/stand/lib/biosmca.S
Normal 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
|
31
sys/arch/i386/stand/lib/biosmca.h
Normal file
31
sys/arch/i386/stand/lib/biosmca.h
Normal 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;
|
78
sys/arch/i386/stand/lib/biosmem.S
Normal file
78
sys/arch/i386/stand/lib/biosmem.S
Normal 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
|
||||
|
87
sys/arch/i386/stand/lib/biosmemps2.S
Normal file
87
sys/arch/i386/stand/lib/biosmemps2.S
Normal 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
|
167
sys/arch/i386/stand/lib/biosmemx.S
Normal file
167
sys/arch/i386/stand/lib/biosmemx.S
Normal 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
|
96
sys/arch/i386/stand/lib/biospci.c
Normal file
96
sys/arch/i386/stand/lib/biospci.c
Normal 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;
|
||||
}
|
57
sys/arch/i386/stand/lib/biosreboot.S
Normal file
57
sys/arch/i386/stand/lib/biosreboot.S
Normal 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
|
358
sys/arch/i386/stand/lib/biosvbe.S
Normal file
358
sys/arch/i386/stand/lib/biosvbe.S
Normal 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
|
||||
|
65
sys/arch/i386/stand/lib/biosvideomode.S
Normal file
65
sys/arch/i386/stand/lib/biosvideomode.S
Normal 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
|
15
sys/arch/i386/stand/lib/boot_params.S
Normal file
15
sys/arch/i386/stand/lib/boot_params.S
Normal 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 */
|
45
sys/arch/i386/stand/lib/bootinfo.c
Normal file
45
sys/arch/i386/stand/lib/bootinfo.c
Normal 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);
|
||||
}
|
48
sys/arch/i386/stand/lib/bootinfo.h
Normal file
48
sys/arch/i386/stand/lib/bootinfo.h
Normal 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);
|
181
sys/arch/i386/stand/lib/bootinfo_biosgeom.c
Normal file
181
sys/arch/i386/stand/lib/bootinfo_biosgeom.c
Normal 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));
|
||||
}
|
61
sys/arch/i386/stand/lib/bootinfo_memmap.c
Normal file
61
sys/arch/i386/stand/lib/bootinfo_memmap.c
Normal 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));
|
||||
}
|
386
sys/arch/i386/stand/lib/bootmenu.c
Normal file
386
sys/arch/i386/stand/lib/bootmenu.c
Normal 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 */
|
53
sys/arch/i386/stand/lib/bootmenu.h
Normal file
53
sys/arch/i386/stand/lib/bootmenu.h
Normal 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 */
|
45
sys/arch/i386/stand/lib/bootmod.h
Normal file
45
sys/arch/i386/stand/lib/bootmod.h
Normal 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 */
|
148
sys/arch/i386/stand/lib/comio.S
Normal file
148
sys/arch/i386/stand/lib/comio.S
Normal 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
|
243
sys/arch/i386/stand/lib/comio_direct.c
Normal file
243
sys/arch/i386/stand/lib/comio_direct.c
Normal 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... */
|
||||
}
|
6
sys/arch/i386/stand/lib/comio_direct.h
Normal file
6
sys/arch/i386/stand/lib/comio_direct.h
Normal 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);
|
126
sys/arch/i386/stand/lib/conio.S
Normal file
126
sys/arch/i386/stand/lib/conio.S
Normal 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
|
152
sys/arch/i386/stand/lib/cpufunc.S
Normal file
152
sys/arch/i386/stand/lib/cpufunc.S
Normal 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
|
49
sys/arch/i386/stand/lib/cpufunc.h
Normal file
49
sys/arch/i386/stand/lib/cpufunc.h
Normal 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);
|
119
sys/arch/i386/stand/lib/crt/dos/doscommain.c
Normal file
119
sys/arch/i386/stand/lib/crt/dos/doscommain.c
Normal 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);
|
||||
}
|
620
sys/arch/i386/stand/lib/crt/dos/start_dos.S
Normal file
620
sys/arch/i386/stand/lib/crt/dos/start_dos.S
Normal 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
|
57
sys/arch/i386/stand/lib/diskbuf.c
Normal file
57
sys/arch/i386/stand/lib/diskbuf.c
Normal 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;
|
||||
}
|
40
sys/arch/i386/stand/lib/diskbuf.h
Normal file
40
sys/arch/i386/stand/lib/diskbuf.h
Normal 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 *);
|
203
sys/arch/i386/stand/lib/dos_file.S
Normal file
203
sys/arch/i386/stand/lib/dos_file.S
Normal 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
|
240
sys/arch/i386/stand/lib/dosfile.c
Normal file
240
sys/arch/i386/stand/lib/dosfile.c
Normal 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;
|
||||
}
|
29
sys/arch/i386/stand/lib/dosfile.h
Normal file
29
sys/arch/i386/stand/lib/dosfile.h
Normal 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);
|
59
sys/arch/i386/stand/lib/dump_eax.S
Normal file
59
sys/arch/i386/stand/lib/dump_eax.S
Normal 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
|
743
sys/arch/i386/stand/lib/exec.c
Normal file
743
sys/arch/i386/stand/lib/exec.c
Normal 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);
|
||||
}
|
80
sys/arch/i386/stand/lib/gatea20.c
Normal file
80
sys/arch/i386/stand/lib/gatea20.c
Normal 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);
|
||||
}
|
93
sys/arch/i386/stand/lib/getextmemx.c
Normal file
93
sys/arch/i386/stand/lib/getextmemx.c
Normal 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;
|
||||
}
|
41
sys/arch/i386/stand/lib/getsecs.c
Normal file
41
sys/arch/i386/stand/lib/getsecs.c
Normal 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;
|
||||
}
|
43
sys/arch/i386/stand/lib/isadma.c
Normal file
43
sys/arch/i386/stand/lib/isadma.c
Normal 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);
|
||||
}
|
||||
}
|
3
sys/arch/i386/stand/lib/isadmavar.h
Normal file
3
sys/arch/i386/stand/lib/isadmavar.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
/* $NetBSD: isadmavar.h,v 1.2 2008/12/14 17:03:43 christos Exp $ */
|
||||
|
||||
void isa_dmacascade(int);
|
231
sys/arch/i386/stand/lib/isapnp.c
Normal file
231
sys/arch/i386/stand/lib/isapnp.c
Normal 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 */
|
||||
}
|
29
sys/arch/i386/stand/lib/isapnpvar.h
Normal file
29
sys/arch/i386/stand/lib/isapnpvar.h
Normal 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*);
|
145
sys/arch/i386/stand/lib/libi386.h
Normal file
145
sys/arch/i386/stand/lib/libi386.h
Normal 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 *);
|
84
sys/arch/i386/stand/lib/menuutils.c
Normal file
84
sys/arch/i386/stand/lib/menuutils.c
Normal 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);
|
||||
}
|
||||
}
|
79
sys/arch/i386/stand/lib/message.S
Normal file
79
sys/arch/i386/stand/lib/message.S
Normal 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
|
87
sys/arch/i386/stand/lib/message32.S
Normal file
87
sys/arch/i386/stand/lib/message32.S
Normal 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
|
124
sys/arch/i386/stand/lib/multiboot.S
Normal file
124
sys/arch/i386/stand/lib/multiboot.S
Normal 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
|
227
sys/arch/i386/stand/lib/netif/3c509.c
Normal file
227
sys/arch/i386/stand/lib/netif/3c509.c
Normal 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;
|
||||
}
|
393
sys/arch/i386/stand/lib/netif/3c509.h
Normal file
393
sys/arch/i386/stand/lib/netif/3c509.h
Normal 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
|
161
sys/arch/i386/stand/lib/netif/3c590.c
Normal file
161
sys/arch/i386/stand/lib/netif/3c590.c
Normal 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;
|
||||
}
|
449
sys/arch/i386/stand/lib/netif/3c90xb.c
Normal file
449
sys/arch/i386/stand/lib/netif/3c90xb.c
Normal 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;
|
||||
}
|
36
sys/arch/i386/stand/lib/netif/Makefile.inc
Normal file
36
sys/arch/i386/stand/lib/netif/Makefile.inc
Normal 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
|
280
sys/arch/i386/stand/lib/netif/am7990.c
Normal file
280
sys/arch/i386/stand/lib/netif/am7990.c
Normal 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;
|
||||
}
|
362
sys/arch/i386/stand/lib/netif/dp8390.c
Normal file
362
sys/arch/i386/stand/lib/netif/dp8390.c
Normal 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;
|
||||
}
|
33
sys/arch/i386/stand/lib/netif/dp8390.h
Normal file
33
sys/arch/i386/stand/lib/netif/dp8390.h
Normal 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 */
|
336
sys/arch/i386/stand/lib/netif/elink3.c
Normal file
336
sys/arch/i386/stand/lib/netif/elink3.c
Normal 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);
|
||||
}
|
39
sys/arch/i386/stand/lib/netif/etherdrv.h
Normal file
39
sys/arch/i386/stand/lib/netif/etherdrv.h
Normal 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
|
492
sys/arch/i386/stand/lib/netif/i82557.c
Normal file
492
sys/arch/i386/stand/lib/netif/i82557.c
Normal 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);
|
||||
}
|
||||
}
|
113
sys/arch/i386/stand/lib/netif/lance.h
Normal file
113
sys/arch/i386/stand/lib/netif/lance.h
Normal 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 */
|
274
sys/arch/i386/stand/lib/netif/ne.c
Normal file
274
sys/arch/i386/stand/lib/netif/ne.c
Normal 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
|
||||
}
|
4
sys/arch/i386/stand/lib/netif/ne.h
Normal file
4
sys/arch/i386/stand/lib/netif/ne.h
Normal 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);
|
165
sys/arch/i386/stand/lib/netif/netif_small.c
Normal file
165
sys/arch/i386/stand/lib/netif/netif_small.c
Normal 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;
|
||||
}
|
35
sys/arch/i386/stand/lib/netif/netif_small.h
Normal file
35
sys/arch/i386/stand/lib/netif/netif_small.h
Normal 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);
|
89
sys/arch/i386/stand/lib/netif/pcnet_isapnp.c
Normal file
89
sys/arch/i386/stand/lib/netif/pcnet_isapnp.c
Normal 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;
|
||||
}
|
99
sys/arch/i386/stand/lib/netif/pcnet_pci.c
Normal file
99
sys/arch/i386/stand/lib/netif/pcnet_pci.c
Normal 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;
|
||||
}
|
323
sys/arch/i386/stand/lib/netif/wd80x3.c
Normal file
323
sys/arch/i386/stand/lib/netif/wd80x3.c
Normal 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
Loading…
Reference in a new issue