PC98 version of new boot loader. Because boot2 has not yet ported,
files in boot2 directory are copies from legacy biosboot. Submitted by: IMAI Takeshi <take-i@ceres.dti.ne.jp>
This commit is contained in:
parent
03126f3524
commit
dccbc08d92
@ -2,6 +2,6 @@
|
||||
SUBDIR+= ficl
|
||||
|
||||
# Pick the machine-dependant subdir based on the target architecture.
|
||||
SUBDIR+= ${MACHINE_ARCH}
|
||||
SUBDIR+= ${MACHINE}
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -29,7 +29,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: isapnp.h,v 1.1 1998/09/18 00:24:25 msmith Exp $
|
||||
* $Id: isapnp.h,v 1.2 1998/10/21 20:07:04 msmith Exp $
|
||||
*/
|
||||
|
||||
#ifndef _I386_ISA_PNP_H_
|
||||
@ -44,7 +44,8 @@
|
||||
#define MAX_PNP_LDN 20
|
||||
|
||||
/* Static ports to access PnP state machine */
|
||||
#if defined(PC98) && defined(KERNEL)
|
||||
#ifndef KERNEL
|
||||
#ifdef PC98
|
||||
/* pnp.h is included from pnpinfo.c. */
|
||||
#define _PNP_ADDRESS 0x259
|
||||
#define _PNP_WRITE_DATA 0xa59
|
||||
@ -52,6 +53,7 @@
|
||||
#define _PNP_ADDRESS 0x279
|
||||
#define _PNP_WRITE_DATA 0xa79
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */
|
||||
#define SET_RD_DATA 0x00
|
||||
|
5
sys/boot/pc98/Makefile
Normal file
5
sys/boot/pc98/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $Id: Makefile,v 1.7 1998/10/14 20:40:56 rnordier Exp $
|
||||
|
||||
SUBDIR= btx boot2 libpc98 loader
|
||||
|
||||
.include <bsd.subdir.mk>
|
97
sys/boot/pc98/boot2/Makefile
Normal file
97
sys/boot/pc98/boot2/Makefile
Normal file
@ -0,0 +1,97 @@
|
||||
# $Id: Makefile,v 1.22 1999/01/04 08:02:13 kato Exp $
|
||||
#
|
||||
|
||||
PROG= boot
|
||||
# Order is very important on the SRCS line for this prog
|
||||
SRCS= start.S table.c boot2.S boot.c asm.S bios.S serial.S
|
||||
SRCS+= probe_keyboard.c io.c disk.c sys.c
|
||||
|
||||
BINDIR= /boot
|
||||
BINMODE= 444
|
||||
CFLAGS= -O2 -malign-functions=0 -malign-jumps=0 -malign-loops=0 \
|
||||
-mno-486 \
|
||||
-DPC98 -DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
|
||||
CFLAGS+= -DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
|
||||
CFLAGS+= ${CWARNFLAGS}
|
||||
CFLAGS+= -I${.CURDIR}/../../.. -aout
|
||||
|
||||
|
||||
# By default, if a serial port is going to be used as console, use COM1
|
||||
# (aka /dev/ttyd0).
|
||||
#BOOT_COMCONSOLE_PORT?=0x30
|
||||
BOOT_COMCONSOLE_PORT?=0x238
|
||||
BOOT_COMCONSOLE_CLK?=16
|
||||
BOOT_COMCONSOLE_MODE=0x0c
|
||||
CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
|
||||
-DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \
|
||||
-DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE}
|
||||
|
||||
# feature not implemented
|
||||
BOOT_COMCONSOLE_SPEED?=9600
|
||||
CFLAGS+= -DCONSPEED=${BOOT_COMCONSOLE_SPEED}
|
||||
|
||||
# Enable code to take the default boot string from a fixed location on the
|
||||
# disk. See nextboot(8) and README.386BSD for more info.
|
||||
#CFLAGS+= -DNAMEBLOCK
|
||||
#CFLAGS+= -DNAMEBLOCK_WRITEBACK
|
||||
|
||||
# Bias the conversion from the BIOS drive number to the FreeBSD unit number
|
||||
# for hard disks. This may be useful for people booting in a mixed IDE/SCSI
|
||||
# environment (set BOOT_HD_BIAS to the number of IDE drives).
|
||||
#CFLAGS+= -DBOOT_HD_BIAS=1
|
||||
#
|
||||
# Details: this only applies if BOOT_HD_BIAS > 0. If the BIOS drive number
|
||||
# for the boot drive is >= BOOT_HD_BIAS, then the boot drive is assumed to
|
||||
# be SCSI and have unit number (BIOS_drive_number - BOOT_HD_BIAS). E.g.,
|
||||
# BOOT_HD_BIAS=1 makes BIOS drive 1 correspond to 1:da(0,a) instead of
|
||||
# 1:wd(1,a). If `da' is given explicitly, then the drive is assumed to be
|
||||
# SCSI and have BIOS drive number (da_unit_number + BOOT_HD_BIAS). E.g.,
|
||||
# BOOT_HD_BIAS=1 makes da(0,a) correspond to 1:da(0,a) instead of 0:da(0,a).
|
||||
|
||||
CLEANFILES+= boot.nohdr boot.strip boot1 boot2 sizetest
|
||||
LDFLAGS+= -N -T 0 -nostdlib
|
||||
NOSHARED= YES
|
||||
NOMAN=
|
||||
STRIP=
|
||||
|
||||
# tunable timeout parameter, waiting for keypress, calibrated in ms
|
||||
BOOTWAIT?= 5000
|
||||
# tunable timeout during string input, calibrated in ms
|
||||
#TIMEOUT?= 30000
|
||||
|
||||
# Location that boot2 is loaded at
|
||||
BOOTSEG= 0x1000
|
||||
|
||||
# Offset in BOOTSEG for the top of the stack, keep this 16 byte aligned
|
||||
BOOTSTACK= 0xFFF0
|
||||
|
||||
boot.strip: boot
|
||||
cp -p boot boot.strip
|
||||
strip -aout boot.strip
|
||||
size -aout boot.strip
|
||||
|
||||
boot.nohdr: boot.strip
|
||||
dd if=boot.strip of=boot.nohdr ibs=32 skip=1 obs=1024b
|
||||
ls -l boot.nohdr
|
||||
|
||||
boot1: boot.nohdr
|
||||
dd if=boot.nohdr of=boot1 bs=512 count=1
|
||||
|
||||
boot2: boot.nohdr
|
||||
dd if=boot.nohdr of=boot2 bs=512 skip=1
|
||||
@dd if=boot2 skip=14 of=sizetest 2> /dev/null
|
||||
@if [ -s sizetest ] ; then \
|
||||
echo "boot2 is too big" >&2 ; \
|
||||
rm boot2 ; \
|
||||
exit 2 ; \
|
||||
fi
|
||||
|
||||
all: boot1 boot2
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
|
||||
boot1 boot2 ${DESTDIR}${BINDIR}
|
||||
|
||||
|
||||
.include <bsd.kern.mk>
|
||||
.include <bsd.prog.mk>
|
63
sys/boot/pc98/boot2/README.serial.98
Normal file
63
sys/boot/pc98/boot2/README.serial.98
Normal file
@ -0,0 +1,63 @@
|
||||
README.srieal.98
|
||||
シリアルコンソールについて
|
||||
加藤丈典 (kato@eclogite.eps.nagoya-u.ac.jp)
|
||||
KATO Takenori
|
||||
|
||||
FreeBSD(98)のコンソールとして、内蔵RS-232Cポートに接続されたダム端末を
|
||||
使用することができます。これにより、FreeBSD(98)をサーバとして使用する
|
||||
時に、キーボードやモニタを接続しなくてもかまわなくなります。
|
||||
|
||||
シリアルコンソールを使用する際は、このドキュメントおよび、IBM-PC用のカー
|
||||
ネルソースに含まれる、/usr/src/sys/i386/boot/biosboot/READEME.serialを
|
||||
良く読んで下さい。
|
||||
|
||||
FreeBSD(98)でシリアルコンソールを使用する際は、以下の手順を実行して下
|
||||
さい。
|
||||
|
||||
1: ブートコードのコンパイルオプション
|
||||
PC-9801シリーズの場合,キーボードが接続されていない状態と旧型
|
||||
キーボードが接続されている状態とを区別する方法がありません.も
|
||||
し,旧型キーボードを使用していて
|
||||
PROBE_KEYBOARD
|
||||
が有効になっていると,キーボードが認識されずにシリアルコンソー
|
||||
ルが使用されます.また,
|
||||
FORCE_COMCONSOLE
|
||||
が有効になっていると,キーボードの接続状態に関わらずシリアルコ
|
||||
ンソールを使用するようになります.
|
||||
|
||||
2: キーボードを切り離す
|
||||
キーボードを接続せずに、本体を起動させた場合、システム領域のキー
|
||||
ボードタイプが、旧式キーボード(CAPSが機械式のキーボード)と同じ
|
||||
になります。FreeBSD(98)のブートコードは、これを検出して自動的
|
||||
にシリアルコンソールモードに移ります。
|
||||
|
||||
3: 端末を接続する
|
||||
内蔵RS-232Cコネクタにダム端末を接続して下さい。ダム端末が無い
|
||||
場合は、適当なパソコンで通信ソフトウェアを実行させたものや、通
|
||||
信機能つきのワープロなどを使用して下さい。
|
||||
|
||||
FreeBSD(98)のブートコードでは、RS-232Cポートを9600ボー、8ビッ
|
||||
ト、パリティ無しに設定されています。
|
||||
|
||||
4: 本体を起動する
|
||||
ブートブロックは、起動時にキーボードの接続を検査します。もし、
|
||||
キーボードが接続されていなければ、端末に以下のメッセージが表示
|
||||
されます。
|
||||
|
||||
No keyboard found.
|
||||
|
||||
>> FreeBSD BOOT @0x90000 640/25600 k of memory
|
||||
Use hd(1,a)/kernel to boot sd0 when wd0 is also installed.
|
||||
Usage: [[[fd(0,a)]/kernel][-Dabcdhrsv]]
|
||||
Use ? for file list or press Enter for defaults
|
||||
|
||||
Boot:
|
||||
|
||||
これは、普段見ているメッセージとほとんど変わりませんが、はじめ
|
||||
に、`No keyboard found'と表示されています。ここで、ダム端末か
|
||||
ら、コンソール上で起動している時と同じようにカーネルを立ち上げ
|
||||
ることができます。起動後のメッセージはダム端末に表示されます。
|
||||
|
||||
もし、シリアルコンソールから通常のコンソールに切替えるには、
|
||||
`-h'オプションをつけて起動して下さい。
|
||||
|
244
sys/boot/pc98/boot2/asm.S
Normal file
244
sys/boot/pc98/boot2/asm.S
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:34:13 rpd
|
||||
* $Id: asm.S,v 1.4 1997/09/01 10:38:24 kato Exp $
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
.file "asm.s"
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
|
||||
CR0_PE_ON = 0x1
|
||||
CR0_PE_OFF = 0xfffffffe
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
*
|
||||
* real_to_prot()
|
||||
* transfer from real mode to protected mode.
|
||||
*/
|
||||
|
||||
ENTRY(real_to_prot)
|
||||
/* guarantee that interrupt is disabled when in prot mode */
|
||||
cli
|
||||
|
||||
/* load the gdtr */
|
||||
addr32
|
||||
data32
|
||||
lgdt EXT(Gdtr)
|
||||
|
||||
/* set the PE bit of CR0 */
|
||||
mov %cr0, %eax
|
||||
|
||||
data32
|
||||
or $CR0_PE_ON, %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
/*
|
||||
* make intrasegment jump to flush the processor pipeline and
|
||||
* reload CS register
|
||||
*/
|
||||
data32
|
||||
ljmp $0x18, $xprot
|
||||
xprot:
|
||||
|
||||
/*
|
||||
* we are in USE32 mode now
|
||||
* set up the protected mode segment registers : DS, SS, ES, FS
|
||||
*/
|
||||
movw $0x20, %ax /* data segment */
|
||||
mov %ax, %ds /* gas would waste a prefix byte for movw */
|
||||
mov %ax, %ss
|
||||
mov %ax, %es
|
||||
movw $0x10, %ax /* flat segment */
|
||||
mov %ax, %fs
|
||||
|
||||
#ifdef BDE_DEBUGGER
|
||||
/* load idtr so we can debug */
|
||||
lidt EXT(Idtr_prot)
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
*
|
||||
* prot_to_real()
|
||||
* transfer from protected mode to real mode
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(prot_to_real)
|
||||
|
||||
/* Prepare %ax while we're still in a mode that gas understands. */
|
||||
movw $0x30, %ax
|
||||
|
||||
/* Change to use16 mode. */
|
||||
ljmp $0x28, $x16
|
||||
x16:
|
||||
|
||||
mov %ax, %ds
|
||||
mov %ax, %ss
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
|
||||
/* clear the PE bit of CR0 */
|
||||
mov %cr0, %eax
|
||||
data32
|
||||
and $CR0_PE_OFF, %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
/*
|
||||
* make intersegment jmp to flush the processor pipeline
|
||||
* and reload CS register
|
||||
*/
|
||||
data32
|
||||
ljmp $BOOTSEG, $xreal
|
||||
xreal:
|
||||
|
||||
/*
|
||||
* we are in real mode now
|
||||
* set up the real mode segment registers : DS, SS, ES, FS
|
||||
*/
|
||||
mov %cs, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %ss
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
|
||||
#ifdef BDE_DEBUGGER
|
||||
/* load idtr so we can debug */
|
||||
addr32
|
||||
data32
|
||||
lidt EXT(Idtr_real)
|
||||
#endif
|
||||
|
||||
data32
|
||||
ret
|
||||
|
||||
/*
|
||||
* startprog(phyaddr)
|
||||
* start the program on protected mode where phyaddr is the entry point
|
||||
*
|
||||
* XXX This whole mess should go away and we should run the boot code in
|
||||
* flat 32 bit mode with it linked -T BOOTSEG. See the netboot code for
|
||||
* how this is done.
|
||||
*/
|
||||
|
||||
ENTRY(startprog)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
movl %esp, %eax /* Use eax as the old stack pointer */
|
||||
|
||||
/* convert the current stack to a 32 bit flat model */
|
||||
movw $0x10, %bx
|
||||
mov %bx, %ss
|
||||
addl $(BOOTSEG<<4),%esp
|
||||
|
||||
/* copy the arguments from the old stack to the new stack */
|
||||
pushl 0x14(%eax) /* &bootinfo */
|
||||
pushl $0 /* was &nfsdiskless */
|
||||
pushl $0 /* was esym */
|
||||
pushl $0 /* was cyloffset */
|
||||
pushl 0x10(%eax) /* bootdev */
|
||||
pushl 0x0C(%eax) /* howto */
|
||||
movl $(ourreturn),%ebx
|
||||
addl $(BOOTSEG<<4),%ebx /* Fix it up for flat segments */
|
||||
pushl %ebx /* our return address */
|
||||
|
||||
/* push on our entry address */
|
||||
pushl $0x08 /* segment selector */
|
||||
pushl 0x08(%eax) /* kernel entry address */
|
||||
|
||||
/* convert over the other data segs */
|
||||
movw $0x10, %bx
|
||||
mov %bx, %ds
|
||||
mov %bx, %es
|
||||
|
||||
/* convert the PC (and code seg) */
|
||||
lret
|
||||
ourreturn:
|
||||
/* For now there is not much we can do, just lock in a loop */
|
||||
jmp ourreturn
|
||||
|
||||
/*
|
||||
* pcpy(src, dst, cnt)
|
||||
* where src is a virtual address and dst is a physical address
|
||||
*/
|
||||
|
||||
ENTRY(pcpy)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %es
|
||||
push %esi
|
||||
push %edi
|
||||
push %ecx
|
||||
|
||||
cld
|
||||
|
||||
/* set %es to point at the flat segment */
|
||||
movw $0x10, %ax
|
||||
mov %ax, %es
|
||||
|
||||
mov 0x8(%ebp), %esi /* source */
|
||||
mov 0xc(%ebp), %edi /* destination */
|
||||
mov 0x10(%ebp), %ecx /* count */
|
||||
|
||||
rep
|
||||
movsb
|
||||
|
||||
pop %ecx
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %es
|
||||
pop %ebp
|
||||
|
||||
ret
|
144
sys/boot/pc98/boot2/asm.h
Normal file
144
sys/boot/pc98/boot2/asm.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.7 92/02/29 15:33:41 rpd
|
||||
* $Id: asm.h,v 1.3 1997/02/22 09:43:04 peter Exp $
|
||||
*/
|
||||
|
||||
#define S_ARG0 4(%esp)
|
||||
#define S_ARG1 8(%esp)
|
||||
#define S_ARG2 12(%esp)
|
||||
#define S_ARG3 16(%esp)
|
||||
|
||||
#define FRAME pushl %ebp; movl %esp, %ebp
|
||||
#define EMARF leave
|
||||
|
||||
#define B_ARG0 8(%ebp)
|
||||
#define B_ARG1 12(%ebp)
|
||||
#define B_ARG2 16(%ebp)
|
||||
#define B_ARG3 20(%ebp)
|
||||
|
||||
#ifdef wheeze
|
||||
|
||||
#define ALIGN 4
|
||||
#define EXT(x) x
|
||||
#define LEXT(x) x:
|
||||
#define LCL(x) ./**/x
|
||||
|
||||
#define LB(x,n) ./**/x
|
||||
#define LBb(x,n) ./**/x
|
||||
#define LBf(x,n) ./**/x
|
||||
|
||||
#define SVC lcall $7,$0
|
||||
|
||||
#define String .string
|
||||
#define Value .value
|
||||
#define Times(a,b) [a\*b]
|
||||
#define Divide(a,b) [a\\b]
|
||||
|
||||
#define INB inb (%dx)
|
||||
#define OUTB outb (%dx)
|
||||
#define INL inl (%dx)
|
||||
#define OUTL outl (%dx)
|
||||
|
||||
#else wheeze
|
||||
#define ALIGN
|
||||
#define LCL(x) x
|
||||
|
||||
#define LB(x,n) n
|
||||
#ifdef __STDC__
|
||||
#define EXT(x) _ ## x
|
||||
#define LEXT(x) _ ## x ## :
|
||||
|
||||
#define LBb(x,n) n ## b
|
||||
#define LBf(x,n) n ## f
|
||||
#else __STDC__
|
||||
#define EXT(x) _/**/x
|
||||
#define LEXT(x) _/**/x/**/:
|
||||
#define LBb(x,n) n/**/b
|
||||
#define LBf(x,n) n/**/f
|
||||
#endif __STDC__
|
||||
#define SVC .byte 0x9a; .long 0; .word 0x7
|
||||
|
||||
#define String .ascii
|
||||
#define Value .word
|
||||
#define Times(a,b) (a*b)
|
||||
#define Divide(a,b) (a/b)
|
||||
|
||||
#define INB inb %dx, %al
|
||||
#define OUTB outb %al, %dx
|
||||
#define INL inl %dx, %eax
|
||||
#define OUTL outl %eax, %dx
|
||||
|
||||
#endif wheeze
|
||||
|
||||
#define addr32 .byte 0x67
|
||||
#define data32 .byte 0x66
|
||||
|
||||
#ifdef GPROF
|
||||
#ifdef __STDC__
|
||||
|
||||
#define MCOUNT .data; LB(x, 9); .long 0; .text; lea LBb(x, 9),%edx; call mcount
|
||||
#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \
|
||||
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
|
||||
#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
|
||||
.align ALIGN; LEXT(x) LEXT(y) ; \
|
||||
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
|
||||
#define ASENTRY(x) .globl x; .align ALIGN; x ## : ; \
|
||||
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
|
||||
|
||||
#else __STDC__
|
||||
|
||||
#define MCOUNT .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
|
||||
#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \
|
||||
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
|
||||
#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
|
||||
.align ALIGN; LEXT(x) LEXT(y)
|
||||
#define ASENTRY(x) .globl x; .align ALIGN; x: ; \
|
||||
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
|
||||
|
||||
#endif __STDC__
|
||||
#else GPROF
|
||||
#ifdef __STDC__
|
||||
|
||||
#define MCOUNT
|
||||
#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x)
|
||||
#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
|
||||
.align ALIGN; LEXT(x) LEXT(y)
|
||||
#define ASENTRY(x) .globl x; .align ALIGN; x ## :
|
||||
|
||||
#else __STDC__
|
||||
|
||||
#define MCOUNT
|
||||
#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x)
|
||||
#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
|
||||
.align ALIGN; LEXT(x) LEXT(y)
|
||||
#define ASENTRY(x) .globl x; .align ALIGN; x:
|
||||
|
||||
#endif __STDC__
|
||||
#endif GPROF
|
||||
|
||||
#define Entry(x) .globl EXT(x); .align ALIGN; LEXT(x)
|
||||
#define DATA(x) .globl EXT(x); .align ALIGN; LEXT(x)
|
456
sys/boot/pc98/boot2/bios.S
Normal file
456
sys/boot/pc98/boot2/bios.S
Normal file
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
|
||||
* $Id: bios.S,v 1.9 1998/05/02 02:06:07 kato Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
/*
|
||||
* Ported to PC-9801 by Yoshio Kimura
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extensions for El Torito CD-ROM booting:
|
||||
*
|
||||
* Copyright © 1997 Pluto Technologies International, Inc. Boulder CO
|
||||
* Copyright © 1997 interface business GmbH, Dresden.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code has been written by Jörg Wunsch, Dresden.
|
||||
* Direct comments to <joerg_wunsch@interface-business.de>.
|
||||
*
|
||||
* 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(S) ``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(S) 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.
|
||||
*
|
||||
*/
|
||||
|
||||
.file "bios.s"
|
||||
|
||||
#include "asm.h"
|
||||
.text
|
||||
|
||||
#ifndef CDBOOT
|
||||
|
||||
/*
|
||||
* biosread(dev, cyl, head, sec, nsec, offset)
|
||||
* Read "nsec" sectors from disk to offset "offset" in boot segment
|
||||
* BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
|
||||
* Call with %ah = 0xd6(for floppy disk) or 0x06(for hard disk)
|
||||
* %al = DA/UA
|
||||
* %bx = data length
|
||||
* %ch = sector size(for floppy) or cylinder(for hard)
|
||||
* %cl = cylinder
|
||||
* %dh = head
|
||||
* %dl = sector
|
||||
* %es:%bp = segment:offset of buffer
|
||||
* Return:
|
||||
* %al = 0x0 on success; err code on failure
|
||||
*/
|
||||
|
||||
ENTRY(biosread)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
|
||||
push %ebx
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
movb 0x14(%ebp), %dl /* sector */
|
||||
movb 0x10(%ebp), %dh /* head */
|
||||
movw 0x0c(%ebp), %cx /* cylinder */
|
||||
movb 0x08(%ebp), %al /* DA/UA */
|
||||
movb $0x06, %ah
|
||||
andb $0xf0, %al
|
||||
cmpb $0x30, %al
|
||||
jz fd
|
||||
cmpb $0x90, %al
|
||||
jnz 1f
|
||||
fd:
|
||||
incb %dl
|
||||
movb $0x02, %ch
|
||||
movb $0xd6, %ah
|
||||
1:
|
||||
movb 0x08(%ebp), %al
|
||||
movl %eax, %ebx
|
||||
|
||||
/* prot_to_real will set %es to BOOTSEG */
|
||||
call EXT(prot_to_real) /* enter real mode */
|
||||
mov %ebx, %eax
|
||||
xor %ebx, %ebx
|
||||
addr32
|
||||
movb 0x18(%ebp), %bl /* number of sectors */
|
||||
data32
|
||||
shl $9, %ebx
|
||||
data32
|
||||
push %ebx
|
||||
addr32
|
||||
data32
|
||||
mov 0x1c(%ebp), %ebx
|
||||
data32
|
||||
mov %ebx, %ebp
|
||||
data32
|
||||
pop %ebx
|
||||
|
||||
int $0x1b
|
||||
jc 1f
|
||||
xor %eax, %eax
|
||||
1:
|
||||
/* save return value (actually movw %ax, %bx) */
|
||||
mov %eax, %ebx
|
||||
|
||||
data32
|
||||
call EXT(real_to_prot) /* back to protected mode */
|
||||
|
||||
xor %eax, %eax
|
||||
movb %bh, %al /* return value in %ax */
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
|
||||
ret
|
||||
|
||||
#else /* CDBOOT */
|
||||
|
||||
|
||||
/*
|
||||
* int
|
||||
* getbootspec(struct specpacket *offset)
|
||||
*
|
||||
* Read CD-ROM boot specification packet to "offset".
|
||||
*/
|
||||
ENTRY(getbootspec)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
|
||||
push %esi
|
||||
push %ebx
|
||||
|
||||
movw 0x8(%ebp), %si
|
||||
mov $0x7f, %edx
|
||||
|
||||
/* prot_to_real will set %es to BOOTSEG */
|
||||
call EXT(prot_to_real) /* enter real mode */
|
||||
movw $0x4b01, %ax /* (do not) terminate disk emulation */
|
||||
movb $0x7f, %dl /* any drive */
|
||||
|
||||
sti
|
||||
int $0x13
|
||||
cli
|
||||
|
||||
/* save return value (actually movw %ax, %bx) */
|
||||
mov %eax, %ebx
|
||||
|
||||
data32
|
||||
call EXT(real_to_prot) /* back to protected mode */
|
||||
|
||||
xor %eax, %eax
|
||||
movb %bh, %al /* return value in %ax */
|
||||
|
||||
pop %ebx
|
||||
pop %esi
|
||||
pop %ebp
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* int
|
||||
* biosreadlba(struct daddrpacket *daddr)
|
||||
* Read sectors using the BIOS "read extended" function
|
||||
* BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
|
||||
* Call with %ah = 0x42
|
||||
* %dl = drive (0x0 for floppy disk, or emulated CD)
|
||||
* %ds:%si = ptr to disk address packet
|
||||
* Return:
|
||||
* %ah = 0x0 on success; err code on failure
|
||||
*/
|
||||
|
||||
ENTRY(biosreadlba)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
|
||||
push %ebx
|
||||
push %esi
|
||||
|
||||
movw 8(%ebp), %si
|
||||
movl $0, %edx /* emulated CD is always drive 0 */
|
||||
|
||||
/* prot_to_real will set %es to BOOTSEG */
|
||||
call EXT(prot_to_real) /* enter real mode */
|
||||
movw $0x4200, %ax /* subfunction */
|
||||
movb $0, %dl
|
||||
|
||||
sti
|
||||
int $0x13
|
||||
cli
|
||||
|
||||
/* save return value (actually movw %ax, %bx) */
|
||||
mov %eax, %ebx
|
||||
|
||||
data32
|
||||
call EXT(real_to_prot) /* back to protected mode */
|
||||
|
||||
xor %eax, %eax
|
||||
movb %bh, %al /* return value in %ax */
|
||||
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
|
||||
ret
|
||||
|
||||
#endif /* !CDBOOT */
|
||||
|
||||
/*
|
||||
* getc()
|
||||
* BIOS call "INT 18H Function 00H" to read character from keyboard
|
||||
* Call with %ah = 0x0
|
||||
* Return: %ah = keyboard scan code
|
||||
* %al = ASCII character
|
||||
*/
|
||||
|
||||
ENTRY(getc)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %ebx /* save %ebx */
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
call EXT(prot_to_real)
|
||||
|
||||
movb $0x0, %ah
|
||||
int $0x18
|
||||
|
||||
movb %al, %bl /* real_to_prot uses %eax */
|
||||
|
||||
data32
|
||||
call EXT(real_to_prot)
|
||||
|
||||
xor %eax, %eax
|
||||
movb %bl, %al
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
/*
|
||||
* ischar()
|
||||
* if there is a character pending, return it; otherwise return 0
|
||||
* BIOS call "INT 18H Function 01H" to check whether a character is pending
|
||||
* Call with %ah = 0x1
|
||||
* Return:
|
||||
* If key waiting to be input:
|
||||
* %ah = keyboard scan code
|
||||
* %al = ASCII character
|
||||
* %bh = 1
|
||||
* else
|
||||
* %bh = 0
|
||||
*/
|
||||
ENTRY(ischar)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %ebx
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
call EXT(prot_to_real) /* enter real mode */
|
||||
|
||||
xor %ebx, %ebx
|
||||
movb $0x1, %ah
|
||||
int $0x18
|
||||
andb %bh, %bh
|
||||
data32
|
||||
jz nochar
|
||||
movb %al, %bl
|
||||
|
||||
nochar:
|
||||
data32
|
||||
call EXT(real_to_prot)
|
||||
|
||||
xor %eax, %eax
|
||||
movb %bl, %al
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
*
|
||||
* get_diskinfo(): return a word that represents the
|
||||
* max number of sectors and heads and drives for this device
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(get_diskinfo)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %ebx
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
movb 0x8(%ebp), %dl /* diskinfo(drive #) */
|
||||
call EXT(prot_to_real) /* enter real mode */
|
||||
|
||||
movb %dl, %al /* ask for disk info */
|
||||
andb $0xf0, %al
|
||||
cmpb $0x30, %al
|
||||
jz fdd4
|
||||
cmpb $0x90, %al
|
||||
jz fdd
|
||||
|
||||
movb %dl, %al
|
||||
movb $0x84, %ah
|
||||
|
||||
int $0x1b
|
||||
|
||||
jnc ok
|
||||
/*
|
||||
* Urk. Call failed. It is not supported for floppies by old BIOS's.
|
||||
* Guess it's a 15-sector floppy.
|
||||
*/
|
||||
fdd4:
|
||||
movb $18, %dl
|
||||
jmp 1f
|
||||
fdd:
|
||||
movb $15, %dl /* max sector */
|
||||
1:
|
||||
subb %ah, %ah /* %ax = 0 */
|
||||
movb %al, %al
|
||||
movb %ah, %bh /* %bh = 0 */
|
||||
movb $2, %bl /* %bl bits 0-3 = drive type,
|
||||
bit 2 = 1.2M */
|
||||
movb $79, %ch /* max track */
|
||||
movb $1, %cl /* # floppy drives installed */
|
||||
movb $2, %dh /* max head */
|
||||
/* es:di = parameter table */
|
||||
/* carry = 0 */
|
||||
ok:
|
||||
|
||||
data32
|
||||
call EXT(real_to_prot) /* back to protected mode */
|
||||
|
||||
/*
|
||||
* form a longword representing all this gunk:
|
||||
* 16 bit cylinder
|
||||
* 8 bit head
|
||||
* 8 bit sector
|
||||
*/
|
||||
mov %ecx, %eax
|
||||
sall $16,%eax /* << 16 */
|
||||
movb %dh, %ah /* max head */
|
||||
movb %dl, %al /* max sector (and # sectors) */
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
*
|
||||
* memsize(i) : return the memory size in KB. i == 0 for conventional memory,
|
||||
* i == 1 for extended memory
|
||||
* Both have the return value in AX.
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(memsize)
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %ebx
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
mov 8(%ebp), %ebx
|
||||
|
||||
xor %eax, %eax
|
||||
cmpb $0x01, %bl
|
||||
jnz memcnv
|
||||
memext:
|
||||
movb 0xA1401 - BOOTSEG * 0x10, %al
|
||||
shll $7, %eax
|
||||
xorl %ebx, %ebx
|
||||
movw 0xA1594 - BOOTSEG * 0x10, %bx
|
||||
shll $10, %ebx
|
||||
addl %ebx, %eax
|
||||
jmp xdone
|
||||
|
||||
memcnv:
|
||||
movb 0xA1501 - BOOTSEG * 0x10, %al
|
||||
andb $0x07, %al
|
||||
incl %eax
|
||||
shll $7, %eax
|
||||
|
||||
xdone:
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
447
sys/boot/pc98/boot2/boot.c
Normal file
447
sys/boot/pc98/boot2/boot.c
Normal file
@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, [92/04/03 16:51:14 rvb]
|
||||
* $Id: boot.c,v 1.19 1998/10/11 15:09:14 kato Exp $
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
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 <sys/param.h>
|
||||
#include "boot.h"
|
||||
#include <a.out.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <machine/bootinfo.h>
|
||||
|
||||
#define ouraddr (BOOTSEG << 4) /* XXX */
|
||||
|
||||
#define BOOT_CONFIG_SIZE 512
|
||||
#define BOOT_HELP_SIZE 2048
|
||||
#define KERNEL_CONFIG_SIZE 512
|
||||
#define NAMEBUF_LEN 1024 /* oversized to defend against gets() */
|
||||
|
||||
static char boot_config[BOOT_CONFIG_SIZE];
|
||||
static char boot_help[BOOT_HELP_SIZE];
|
||||
char *name;
|
||||
static char kernel_config[KERNEL_CONFIG_SIZE];
|
||||
static char kernel_config_namebuf[NAMEBUF_LEN + sizeof "config"];
|
||||
static char linebuf[NAMEBUF_LEN];
|
||||
static char namebuf[NAMEBUF_LEN];
|
||||
static struct bootinfo bootinfo;
|
||||
int loadflags;
|
||||
|
||||
static void getbootdev(char *ptr, int *howto);
|
||||
static void loadprog(void);
|
||||
static void readfile(char *path, char *buf, size_t nbytes);
|
||||
|
||||
/* NORETURN */
|
||||
void
|
||||
boot(int drive)
|
||||
{
|
||||
int ret;
|
||||
#ifdef PC98
|
||||
int i;
|
||||
unsigned char disk_equips;
|
||||
#endif
|
||||
|
||||
/* Pick up the story from the Bios on geometry of disks */
|
||||
|
||||
#ifdef PC98
|
||||
for(ret = 0; ret < 2; ret ++) {
|
||||
if (*(unsigned char*)V(0xA155d) & (1 << ret)) {
|
||||
bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80);
|
||||
}
|
||||
#else /* IBM-PC */
|
||||
for(ret = 0; ret < N_BIOS_GEOM; ret ++)
|
||||
bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80);
|
||||
#endif /* PC98 */
|
||||
}
|
||||
|
||||
bootinfo.bi_basemem = memsize(0);
|
||||
bootinfo.bi_extmem = memsize(1);
|
||||
bootinfo.bi_memsizes_valid = 1;
|
||||
|
||||
gateA20();
|
||||
|
||||
#ifdef PC98
|
||||
/* set machine type to PC98_SYSTEM_PARAMETER */
|
||||
machine_check();
|
||||
#endif /* PC98 */
|
||||
|
||||
/*
|
||||
* The default boot device is the first partition in the
|
||||
* compatibility slice on the boot drive.
|
||||
*/
|
||||
dosdev = drive;
|
||||
#ifdef PC98
|
||||
maj = (drive&0x70) >> 3; /* a good first bet */
|
||||
if (maj == 4) { /* sd */
|
||||
disk_equips = *(unsigned char *)V(0xA1482);
|
||||
unit = 0;
|
||||
for (i=0; i<(drive&0x0f); i++) {
|
||||
unit += (disk_equips >> i) & 1;
|
||||
}
|
||||
} else {
|
||||
unit = drive & 0x0f;
|
||||
}
|
||||
#else /* IBM-PC */
|
||||
maj = 2;
|
||||
unit = drive & 0x7f;
|
||||
#ifdef dontneed
|
||||
slice = 0;
|
||||
part = 0;
|
||||
#endif
|
||||
if (drive & 0x80) {
|
||||
/* Hard drive. Adjust. */
|
||||
maj = 0;
|
||||
#if BOOT_HD_BIAS > 0
|
||||
if (unit >= BOOT_HD_BIAS) {
|
||||
/*
|
||||
* The drive is probably a SCSI drive with a unit
|
||||
* number BOOT_HD_BIAS less than the BIOS drive
|
||||
* number.
|
||||
*/
|
||||
maj = 4;
|
||||
unit -= BOOT_HD_BIAS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* PC98 */
|
||||
name = "/boot/loader";
|
||||
if (boot_config[0] != '\0') {
|
||||
printf("boot.config: %s", boot_config);
|
||||
getbootdev(boot_config, &loadflags);
|
||||
if (openrd() != 0)
|
||||
name = "kernel";
|
||||
}
|
||||
loadstart:
|
||||
/* print this all each time.. (saves space to do so) */
|
||||
/* If we have looped, use the previous entries as defaults */
|
||||
printf("\r \n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory, %s%s console\n"
|
||||
"Boot default: %d:%s(%d,%c)%s\n"
|
||||
"%s\n"
|
||||
"boot: ",
|
||||
ouraddr, bootinfo.bi_basemem, bootinfo.bi_extmem,
|
||||
(loadflags & RB_SERIAL) ? "serial" : "internal",
|
||||
(loadflags & RB_DUAL) ? "/dual" : "",
|
||||
#ifdef PC98
|
||||
dosdev & 0x0f, devs[maj], unit, 'a' + part,
|
||||
#else
|
||||
dosdev & 0x7f, devs[maj], unit, 'a' + part,
|
||||
#endif
|
||||
name ? name : "*specify_a_kernel_name*",
|
||||
boot_help);
|
||||
|
||||
/*
|
||||
* Ignore flags from previous attempted boot, if any.
|
||||
* XXX this is now too strict. Settings given in boot.config should
|
||||
* not be changed.
|
||||
*/
|
||||
loadflags &= (RB_DUAL | RB_SERIAL);
|
||||
|
||||
/*
|
||||
* Be paranoid and make doubly sure that the input buffer is empty.
|
||||
*/
|
||||
if (loadflags & (RB_DUAL | RB_SERIAL))
|
||||
init_serial();
|
||||
|
||||
if (!gets(linebuf))
|
||||
putchar('\n');
|
||||
else
|
||||
getbootdev(linebuf, &loadflags);
|
||||
if (name == NULL)
|
||||
goto loadstart;
|
||||
ret = openrd();
|
||||
if (ret != 0) {
|
||||
if (ret > 0)
|
||||
printf("Can't find %s\n", name);
|
||||
goto loadstart;
|
||||
}
|
||||
/* if (inode.i_mode&IEXEC)
|
||||
loadflags |= RB_KDB;
|
||||
*/
|
||||
loadprog();
|
||||
goto loadstart;
|
||||
}
|
||||
|
||||
static void
|
||||
loadprog(void)
|
||||
{
|
||||
struct exec head;
|
||||
int startaddr;
|
||||
int addr; /* physical address.. not directly useable */
|
||||
int bootdev;
|
||||
int i;
|
||||
unsigned pad;
|
||||
char *s, *t;
|
||||
|
||||
read((void *)&head, sizeof(head));
|
||||
if ( N_BADMAG(head)) {
|
||||
printf("Invalid format!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
poff = N_TXTOFF(head);
|
||||
/*if(poff==0)
|
||||
poff = 32;*/
|
||||
|
||||
/*
|
||||
* We assume that the entry address is the same as the lowest text
|
||||
* address and that the kernel startup code handles relocation by
|
||||
* this address rounded down to a multiple of 16M.
|
||||
*/
|
||||
startaddr = head.a_entry & 0x00FFFFFF;
|
||||
addr = startaddr;
|
||||
printf("Booting %d:%s(%d,%c)%s @ 0x%x\n"
|
||||
#ifdef PC98
|
||||
, dosdev & 0x0f
|
||||
#else
|
||||
, dosdev & 0x7f
|
||||
#endif
|
||||
, devs[maj]
|
||||
, unit
|
||||
, 'a'+part
|
||||
, name
|
||||
, addr);
|
||||
if(addr < 0x00100000)
|
||||
{
|
||||
/*
|
||||
* Bail out, instead of risking to damage the BIOS
|
||||
* variables, the loader, or the adapter memory area.
|
||||
* We don't support loading below 1 MB any more.
|
||||
*/
|
||||
printf("Start address too low\n");
|
||||
return;
|
||||
}
|
||||
printf("text=0x%x ", head.a_text);
|
||||
/********************************************************/
|
||||
/* LOAD THE TEXT SEGMENT */
|
||||
/********************************************************/
|
||||
xread((void *)addr, head.a_text);
|
||||
addr += head.a_text;
|
||||
|
||||
/********************************************************/
|
||||
/* Load the Initialised data after the text */
|
||||
/********************************************************/
|
||||
while (addr & PAGE_MASK)
|
||||
*(char *)addr++ = 0;
|
||||
|
||||
printf("data=0x%x ", head.a_data);
|
||||
xread((void *)addr, head.a_data);
|
||||
addr += head.a_data;
|
||||
|
||||
/********************************************************/
|
||||
/* Skip over the uninitialised data */
|
||||
/* (but clear it) */
|
||||
/********************************************************/
|
||||
printf("bss=0x%x ", head.a_bss);
|
||||
|
||||
/*
|
||||
* XXX however, we should be checking that we don't load ... into
|
||||
* nonexistent memory. A full symbol table is unlikely to fit on 4MB
|
||||
* machines.
|
||||
*/
|
||||
/* kzip & kernel will zero their own bss */
|
||||
addr += head.a_bss;
|
||||
|
||||
/* Pad to a page boundary. */
|
||||
pad = (unsigned)addr & PAGE_MASK;
|
||||
if (pad != 0) {
|
||||
pad = PAGE_SIZE - pad;
|
||||
addr += pad;
|
||||
}
|
||||
bootinfo.bi_symtab = addr;
|
||||
|
||||
/********************************************************/
|
||||
/* Copy the symbol table size */
|
||||
/********************************************************/
|
||||
pcpy(&head.a_syms, (void *)addr, sizeof(head.a_syms));
|
||||
addr += sizeof(head.a_syms);
|
||||
|
||||
/********************************************************/
|
||||
/* Load the symbol table */
|
||||
/********************************************************/
|
||||
printf("symbols=[+0x%x+0x%x+0x%x", pad, sizeof(head.a_syms),
|
||||
head.a_syms);
|
||||
xread((void *)addr, head.a_syms);
|
||||
addr += head.a_syms;
|
||||
|
||||
/********************************************************/
|
||||
/* Load the string table size */
|
||||
/********************************************************/
|
||||
read((void *)&i, sizeof(int));
|
||||
pcpy(&i, (void *)addr, sizeof(int));
|
||||
i -= sizeof(int);
|
||||
addr += sizeof(int);
|
||||
|
||||
/********************************************************/
|
||||
/* Load the string table */
|
||||
/********************************************************/
|
||||
printf("+0x%x+0x%x]\n", sizeof(int), i);
|
||||
xread((void *)addr, i);
|
||||
addr += i;
|
||||
|
||||
bootinfo.bi_esymtab = addr;
|
||||
|
||||
/*
|
||||
* For backwards compatibility, use the previously-unused adaptor
|
||||
* and controller bitfields to hold the slice number.
|
||||
*/
|
||||
bootdev = MAKEBOOTDEV(maj, (slice >> 4), slice & 0xf, unit, part);
|
||||
|
||||
bootinfo.bi_version = BOOTINFO_VERSION;
|
||||
bootinfo.bi_kernelname = (u_int32_t)(name + ouraddr);
|
||||
bootinfo.bi_nfs_diskless = 0;
|
||||
bootinfo.bi_size = sizeof(bootinfo);
|
||||
bootinfo.bi_bios_dev = dosdev;
|
||||
|
||||
/*
|
||||
* Load the kernel config file (if any). Its name is given by
|
||||
* appending ".config" to the kernel name. Build the name inline
|
||||
* because no str*() functions are available. The file has to be
|
||||
* copied to &disklabel for userconfig. It can't be loaded there
|
||||
* directly because the label is used late in readfile() in some
|
||||
* unusual cases, e.g., for bad144 handling.
|
||||
*/
|
||||
s = name;
|
||||
t = kernel_config_namebuf;
|
||||
do
|
||||
;
|
||||
while ((*t++ = *s++) != '\0');
|
||||
s = ".config";
|
||||
--t;
|
||||
do
|
||||
;
|
||||
while ((*t++ = *s++) != '\0');
|
||||
readfile(kernel_config_namebuf, kernel_config, KERNEL_CONFIG_SIZE);
|
||||
pcpy(kernel_config, (char *)&disklabel + ouraddr, KERNEL_CONFIG_SIZE);
|
||||
|
||||
printf("total=0x%x entry point=0x%x\n", addr, startaddr);
|
||||
startprog(startaddr, loadflags | RB_BOOTINFO, bootdev,
|
||||
(unsigned)&bootinfo + ouraddr);
|
||||
}
|
||||
|
||||
static void
|
||||
readfile(char *path, char *buf, size_t nbytes)
|
||||
{
|
||||
int openstatus;
|
||||
|
||||
buf[0] = '\0';
|
||||
name = path;
|
||||
openstatus = openrd();
|
||||
if (openstatus != 0) {
|
||||
if (openstatus > 0)
|
||||
printf("Can't find file %s\n", name);
|
||||
} else {
|
||||
/* XXX no way to determine file size. */
|
||||
read(buf, nbytes);
|
||||
}
|
||||
buf[nbytes - 1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
getbootdev(char *ptr, int *howto)
|
||||
{
|
||||
char c;
|
||||
int f;
|
||||
char *p;
|
||||
|
||||
/* Copy the flags to save some bytes. */
|
||||
f = *howto;
|
||||
|
||||
c = *ptr;
|
||||
for (;;) {
|
||||
nextarg:
|
||||
while (c == ' ' || c == '\n')
|
||||
c = *++ptr;
|
||||
if (c == '-')
|
||||
while ((c = *++ptr) != '\0') {
|
||||
if (c == ' ' || c == '\n')
|
||||
goto nextarg;
|
||||
if (c == 'a')
|
||||
f |= RB_ASKNAME;
|
||||
if (c == 'C')
|
||||
f |= RB_CDROM;
|
||||
if (c == 'c')
|
||||
f |= RB_CONFIG;
|
||||
if (c == 'D')
|
||||
f ^= RB_DUAL;
|
||||
if (c == 'd')
|
||||
f |= RB_KDB;
|
||||
if (c == 'g')
|
||||
f |= RB_GDB;
|
||||
if (c == 'h')
|
||||
f ^= RB_SERIAL;
|
||||
if (c == 'P')
|
||||
f |= RB_PROBEKBD;
|
||||
if (c == 'r')
|
||||
f |= RB_DFLTROOT;
|
||||
if (c == 's')
|
||||
f |= RB_SINGLE;
|
||||
if (c == 'v')
|
||||
f |= RB_VERBOSE;
|
||||
}
|
||||
if (c == '\0')
|
||||
break;
|
||||
p = name = namebuf;
|
||||
while (c != '\0' && c != ' ' && c != '\n') {
|
||||
*p++ = c;
|
||||
c = *++ptr;
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
if (f & RB_PROBEKBD) {
|
||||
if (probe_keyboard()) {
|
||||
f |= RB_DUAL | RB_SERIAL;
|
||||
printf("No keyboard found\n");
|
||||
} else
|
||||
printf("Keyboard found\n");
|
||||
}
|
||||
if (f & (RB_DUAL | RB_SERIAL))
|
||||
init_serial();
|
||||
*howto = f;
|
||||
}
|
109
sys/boot/pc98/boot2/boot.h
Normal file
109
sys/boot/pc98/boot2/boot.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:35:03 rpd
|
||||
* $Id: boot.h,v 1.14 1998/10/11 15:08:50 kato Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
|
||||
#define RB_DUAL 0x40000 /* XXX */
|
||||
#define RB_PROBEKBD 0x80000 /* XXX */
|
||||
|
||||
extern char *devs[];
|
||||
extern char *name;
|
||||
extern struct fs *fs;
|
||||
extern struct inode inode;
|
||||
extern int dosdev, unit, slice, part, maj, boff, poff;
|
||||
extern unsigned tw_chars;
|
||||
extern int loadflags;
|
||||
extern struct disklabel disklabel;
|
||||
|
||||
/* asm.S */
|
||||
#if ASM_ONLY
|
||||
void real_to_prot(void);
|
||||
void prot_to_real(void);
|
||||
#endif
|
||||
void startprog(unsigned int physaddr, int howto, int bootdev,
|
||||
/* XXX struct bootinfo * */ unsigned int bootinfo);
|
||||
void pcpy(const void *src, void *dst, size_t count);
|
||||
|
||||
/* bios.S */
|
||||
int biosread(int dev, int cyl, int head, int sec, int nsec, void *offset);
|
||||
void putc(int c);
|
||||
int getc(void);
|
||||
int ischar(void);
|
||||
int get_diskinfo(int drive);
|
||||
int memsize(int extended);
|
||||
|
||||
/* boot.c */
|
||||
void boot(int drive);
|
||||
|
||||
/* boot2.S */
|
||||
void boot2(void);
|
||||
|
||||
/* disk.c */
|
||||
int devopen(void);
|
||||
void devread(char *iodest, int sector, int cnt);
|
||||
|
||||
/* io.c */
|
||||
void gateA20(void);
|
||||
void printf(const char *format, ...);
|
||||
void putchar(int c);
|
||||
void delay1ms(void);
|
||||
int gets(char *buf);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
#ifdef CDBOOT
|
||||
int strcasecmp(const char *s1, const char *s2);
|
||||
#endif /* !CDBOOT */
|
||||
void bcopy(const void *from, void *to, size_t len);
|
||||
void twiddle(void);
|
||||
#ifdef PC98
|
||||
void machine_check(void);
|
||||
#endif
|
||||
|
||||
/* probe_keyboard.c */
|
||||
int probe_keyboard(void);
|
||||
|
||||
/* serial.S */
|
||||
void serial_putc(int ch);
|
||||
int serial_getc(void);
|
||||
int serial_ischar(void);
|
||||
void init_serial(void);
|
||||
|
||||
/* sys.c */
|
||||
void xread(char *addr, int size);
|
||||
void read(char *buffer, int count);
|
||||
int openrd(void);
|
||||
|
||||
#ifdef PC98
|
||||
#define V(ra) (ra - BOOTSEG * 0x10)
|
||||
#endif
|
||||
|
183
sys/boot/pc98/boot2/boot2.S
Normal file
183
sys/boot/pc98/boot2/boot2.S
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:35:26 rpd
|
||||
* boot2.S,v 1.6 1995/01/25 21:37:40 bde Exp
|
||||
*/
|
||||
/*
|
||||
* Ported to PC-9801 by Yoshio Kimura
|
||||
*/
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
/* Conventional GDT indexes. */
|
||||
#define BOOT_CS_INDEX 3
|
||||
#define BOOT_CS16_INDEX 5
|
||||
#define BOOT_DS_INDEX 4
|
||||
|
||||
#ifdef BDE_DEBUGGER
|
||||
#define DB_CS_INDEX 14
|
||||
#define DB_CS16_INDEX 15
|
||||
#define DB_DS_INDEX 16
|
||||
#define GDT_INDEX 17
|
||||
#endif
|
||||
|
||||
/* Vector numbers. */
|
||||
#define BREAKPOINT_VECTOR 3
|
||||
#define DEBUG_VECTOR 1
|
||||
|
||||
/*
|
||||
* boot2() -- second stage boot
|
||||
* SP points to default string if found
|
||||
*/
|
||||
|
||||
ENTRY(boot2)
|
||||
data32
|
||||
subl %eax, %eax
|
||||
mov %cs, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
data32
|
||||
shll $4, %eax
|
||||
|
||||
/* fix up GDT entries for bootstrap */
|
||||
#define FIXUP(gdt_index) \
|
||||
addr32; \
|
||||
movl %eax, EXT(Gdt)+(8*gdt_index)+2; /* actually movw %ax */ \
|
||||
addr32; \
|
||||
movb %bl, EXT(Gdt)+(8*gdt_index)+4
|
||||
|
||||
data32
|
||||
shld $16, %eax, %ebx
|
||||
FIXUP(BOOT_CS_INDEX)
|
||||
FIXUP(BOOT_CS16_INDEX)
|
||||
FIXUP(BOOT_DS_INDEX)
|
||||
|
||||
/* fix up GDT pointer */
|
||||
data32
|
||||
movl %eax, %ecx
|
||||
data32
|
||||
addl $ EXT(Gdt), %eax
|
||||
addr32
|
||||
data32
|
||||
movl %eax, EXT(Gdtr)+2
|
||||
|
||||
#ifdef BDE_DEBUGGER
|
||||
/* fix up GDT entry for GDT */
|
||||
data32
|
||||
shld $16, %eax, %ebx
|
||||
FIXUP(GDT_INDEX)
|
||||
|
||||
/* fix up IDT pointer */
|
||||
data32
|
||||
addl $ EXT(Idt), %ecx
|
||||
addr32
|
||||
data32
|
||||
movl %ecx, EXT(Idtr_prot)+2
|
||||
|
||||
/* %es = vector table segment for a while */
|
||||
push %es
|
||||
data32
|
||||
subl %eax, %eax
|
||||
mov %ax, %es
|
||||
|
||||
/* fix up GDT entries for bdb */
|
||||
data32
|
||||
movl $4*DEBUG_VECTOR, %esi
|
||||
addr32
|
||||
movl %es: 2(%esi), %eax /* actually movw to %ax */
|
||||
data32
|
||||
shll $4, %eax
|
||||
data32
|
||||
shld $16, %eax, %ebx
|
||||
FIXUP(DB_CS_INDEX)
|
||||
FIXUP(DB_CS16_INDEX)
|
||||
FIXUP(DB_DS_INDEX)
|
||||
|
||||
/* Fetch entry points of bdb's protected mode trap handlers. These
|
||||
* are stored at 2 before the corresponding entry points for real mode.
|
||||
*/
|
||||
data32
|
||||
subl %ebx, %ebx
|
||||
addr32
|
||||
movl %es: (%esi), %ebx /* actually movw to %bx */
|
||||
data32
|
||||
subl %ecx, %ecx
|
||||
addr32
|
||||
movl %es: 4*(BREAKPOINT_VECTOR-DEBUG_VECTOR)(%esi), %ecx
|
||||
/* actually movw to %cx */
|
||||
|
||||
/* %es = bdb segment for a while */
|
||||
data32
|
||||
shrl $4, %eax
|
||||
mov %ax, %es
|
||||
|
||||
/* fix up IDT entries for bdb */
|
||||
data32
|
||||
subl $2, %ebx /* calculate EA to check it */
|
||||
jb 1f /* give up if it would trap */
|
||||
addr32
|
||||
movl %es: (%ebx), %eax /* actually movw to %ax */
|
||||
addr32
|
||||
movl %eax, EXT(Idt)+8*DEBUG_VECTOR /* actually movw %ax */
|
||||
1:
|
||||
data32
|
||||
subl $2, %ecx
|
||||
jb 1f
|
||||
addr32
|
||||
movl %es: (%ecx), %eax /* actually movw to %ax */
|
||||
addr32
|
||||
movl %eax, EXT(Idt)+8*BREAKPOINT_VECTOR /* actually movw %ax */
|
||||
1:
|
||||
|
||||
/* finished with groping in real mode segments */
|
||||
pop %es
|
||||
#endif /* BDE_DEBUGGER */
|
||||
|
||||
/* change to protected mode */
|
||||
data32
|
||||
call EXT(real_to_prot)
|
||||
|
||||
/* clear the bss */
|
||||
movl $ EXT(edata), %edi /* no EXT(_edata) - krufty ld */
|
||||
movl $ EXT(end), %ecx /* or EXT(_end) */
|
||||
subl %edi, %ecx
|
||||
subb %al, %al
|
||||
rep
|
||||
stosb
|
||||
|
||||
#ifdef NAMEBLOCK
|
||||
movl %esp, EXT(dflt_name)
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
movb 0xA1584 - BOOTSEG * 0x10, %dl
|
||||
#endif
|
||||
movzbl %dl, %edx /* discard head (%dh) and random high bits */
|
||||
pushl %edx
|
||||
call EXT(boot)
|
||||
oops:
|
||||
hlt
|
||||
jmp oops
|
330
sys/boot/pc98/boot2/disk.c
Normal file
330
sys/boot/pc98/boot2/disk.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:35:49 rpd
|
||||
* $Id: disk.c,v 1.9 1997/05/28 09:22:59 kato Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ported to PC-9801 by Yoshio Kimura
|
||||
*/
|
||||
|
||||
/*
|
||||
* 93/10/08 bde
|
||||
* If there is no 386BSD partition, initialize the label sector with
|
||||
* LABELSECTOR instead of with garbage.
|
||||
*
|
||||
* 93/08/22 bde
|
||||
* Fixed reading of bad sector table. It is at the end of the 'c'
|
||||
* partition, which is not always at the end of the disk.
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
#ifdef DO_BAD144
|
||||
#include <sys/dkbad.h>
|
||||
#endif DO_BAD144
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskslice.h>
|
||||
|
||||
#define BIOS_DEV_FLOPPY 0x0
|
||||
#define BIOS_DEV_WIN 0x80
|
||||
|
||||
#define BPS 512
|
||||
#define SPT(di) ((di)&0xff)
|
||||
#define HEADS(di) (((di)>>8)&0xff)
|
||||
|
||||
#ifdef DO_BAD144
|
||||
static struct dkbad dkb;
|
||||
static int do_bad144;
|
||||
#endif DO_BAD144
|
||||
static int bsize;
|
||||
|
||||
static int spt, spc;
|
||||
|
||||
struct fs *fs;
|
||||
struct inode inode;
|
||||
int dosdev, unit, slice, part, maj, boff;
|
||||
|
||||
/*#define EMBEDDED_DISKLABEL 1*/
|
||||
|
||||
/* Read ahead buffer large enough for one track on a 1440K floppy. 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.
|
||||
*/
|
||||
#define RA_SECTORS 18
|
||||
static char ra_buf[RA_SECTORS * BPS];
|
||||
static int ra_dev;
|
||||
static int ra_end;
|
||||
static int ra_first;
|
||||
|
||||
static int badsect(int sector);
|
||||
static char *Bread(int dosdev, int sector);
|
||||
|
||||
int
|
||||
devopen(void)
|
||||
{
|
||||
struct dos_partition *dptr;
|
||||
struct disklabel *dl;
|
||||
char *p;
|
||||
int i, sector = 0, di, dosdev_copy;
|
||||
|
||||
dosdev_copy = dosdev;
|
||||
di = get_diskinfo(dosdev_copy);
|
||||
spc = (spt = SPT(di)) * HEADS(di);
|
||||
|
||||
#ifndef RAWBOOT
|
||||
if ((dosdev_copy & 0xf0) == 0x90)
|
||||
{
|
||||
boff = 0;
|
||||
part = (spt == 15 ? 0 : 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef EMBEDDED_DISKLABEL
|
||||
dl = &disklabel;
|
||||
#else EMBEDDED_DISKLABEL
|
||||
#ifdef PC98
|
||||
p = Bread(dosdev_copy, 1);
|
||||
dptr = (struct dos_partition *)p;
|
||||
slice = WHOLE_DISK_SLICE;
|
||||
for (i = 0; i < NDOSPART; i++, dptr++)
|
||||
if (dptr->dp_mid == DOSPTYP_386BSD) {
|
||||
slice = BASE_SLICE + i;
|
||||
sector = dptr->dp_scyl * spc;
|
||||
break;
|
||||
}
|
||||
p = Bread(dosdev, sector + LABELSECTOR);
|
||||
dl=((struct disklabel *)p);
|
||||
disklabel = *dl; /* structure copy (maybe useful later)*/
|
||||
#else
|
||||
p = Bread(dosdev_copy, 0);
|
||||
dptr = (struct dos_partition *)(p+DOSPARTOFF);
|
||||
slice = WHOLE_DISK_SLICE;
|
||||
for (i = 0; i < NDOSPART; i++, dptr++)
|
||||
if (dptr->dp_typ == DOSPTYP_386BSD) {
|
||||
slice = BASE_SLICE + i;
|
||||
sector = dptr->dp_start;
|
||||
break;
|
||||
}
|
||||
p = Bread(dosdev_copy, sector + LABELSECTOR);
|
||||
dl=((struct disklabel *)p);
|
||||
disklabel = *dl; /* structure copy (maybe useful later)*/
|
||||
#endif /* PC98 */
|
||||
#endif EMBEDDED_DISKLABEL
|
||||
if (dl->d_magic != DISKMAGIC) {
|
||||
printf("bad disklabel\n");
|
||||
return 1;
|
||||
}
|
||||
if( (maj == 4) || (maj == 0) || (maj == 1))
|
||||
{
|
||||
if (dl->d_type == DTYPE_SCSI)
|
||||
{
|
||||
maj = 4; /* use scsi as boot dev */
|
||||
}
|
||||
else
|
||||
{
|
||||
maj = 0; /* must be ESDI/IDE */
|
||||
}
|
||||
}
|
||||
/* This little trick is for OnTrack DiskManager disks */
|
||||
boff = dl->d_partitions[part].p_offset -
|
||||
dl->d_partitions[2].p_offset + sector;
|
||||
|
||||
#ifndef PC98
|
||||
bsize = dl->d_partitions[part].p_size;
|
||||
if (bsize == 0) {
|
||||
printf("empty partition\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DO_BAD144
|
||||
do_bad144 = 0;
|
||||
if (dl->d_flags & D_BADSECT) {
|
||||
/* this disk uses bad144 */
|
||||
int i;
|
||||
int dkbbnum;
|
||||
struct dkbad *dkbptr;
|
||||
|
||||
/* find the first readable bad sector table */
|
||||
/* some of this code is copied from ufs/ufs_disksubr.c */
|
||||
/* including the bugs :-( */
|
||||
/* read a bad sector table */
|
||||
|
||||
#define BAD144_PART 2 /* XXX scattered magic numbers */
|
||||
#define BSD_PART 0 /* XXX should be 2 but bad144.c uses 0 */
|
||||
if (dl->d_partitions[BSD_PART].p_offset != 0)
|
||||
dkbbnum = dl->d_partitions[BAD144_PART].p_offset
|
||||
+ dl->d_partitions[BAD144_PART].p_size;
|
||||
else
|
||||
dkbbnum = dl->d_secperunit;
|
||||
dkbbnum -= dl->d_nsectors;
|
||||
|
||||
if (dl->d_secsize > DEV_BSIZE)
|
||||
dkbbnum *= dl->d_secsize / DEV_BSIZE;
|
||||
else
|
||||
dkbbnum /= DEV_BSIZE / dl->d_secsize;
|
||||
i = 0;
|
||||
do_bad144 = 0;
|
||||
do {
|
||||
/* XXX: what if the "DOS sector" < 512 bytes ??? */
|
||||
p = Bread(dosdev_copy, dkbbnum + i);
|
||||
dkbptr = (struct dkbad *) p;
|
||||
/* XXX why is this not in <sys/dkbad.h> ??? */
|
||||
#define DKBAD_MAGIC 0x4321
|
||||
if (dkbptr->bt_mbz == 0 &&
|
||||
dkbptr->bt_flag == DKBAD_MAGIC) {
|
||||
dkb = *dkbptr; /* structure copy */
|
||||
do_bad144 = 1;
|
||||
break;
|
||||
}
|
||||
i += 2;
|
||||
} while (i < 10 && (unsigned)i < dl->d_nsectors);
|
||||
if (!do_bad144)
|
||||
printf("Bad bad sector table\n");
|
||||
else
|
||||
printf("Using bad sector table at %d\n", dkbbnum+i);
|
||||
}
|
||||
#endif /* DO_BAD144 */
|
||||
}
|
||||
#endif /* RAWBOOT */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Be aware that cnt is rounded up to N*BPS
|
||||
*/
|
||||
void
|
||||
devread(char *iodest, int sector, int cnt)
|
||||
{
|
||||
int offset;
|
||||
char *p;
|
||||
int dosdev_copy;
|
||||
|
||||
for (offset = 0; offset < cnt; offset += BPS)
|
||||
{
|
||||
dosdev_copy = dosdev;
|
||||
p = Bread(dosdev_copy, badsect(sector++));
|
||||
bcopy(p, iodest+offset, BPS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
Bread(int dosdev, int sector)
|
||||
{
|
||||
if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
|
||||
{
|
||||
int cyl, head, sec, nsec;
|
||||
|
||||
cyl = sector/spc;
|
||||
#ifndef PC98
|
||||
if (cyl > 1023) {
|
||||
printf("Error: C:%d > 1023 (BIOS limit)\n", cyl);
|
||||
for(;;); /* loop forever */
|
||||
}
|
||||
#endif
|
||||
head = (sector % spc) / spt;
|
||||
sec = sector % spt;
|
||||
nsec = spt - sec;
|
||||
if (nsec > RA_SECTORS)
|
||||
nsec = RA_SECTORS;
|
||||
twiddle();
|
||||
if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
|
||||
{
|
||||
nsec = 1;
|
||||
twiddle();
|
||||
while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
|
||||
printf("Error: D:0x%x C:%d H:%d S:%d\n",
|
||||
dosdev, cyl, head, sec);
|
||||
twiddle();
|
||||
}
|
||||
}
|
||||
ra_dev = dosdev;
|
||||
ra_first = sector;
|
||||
ra_end = sector + nsec;
|
||||
}
|
||||
return (ra_buf + (sector - ra_first) * BPS);
|
||||
}
|
||||
|
||||
static int
|
||||
badsect(int sector)
|
||||
{
|
||||
#if defined(DO_BAD144) && !defined(RAWBOOT)
|
||||
int i;
|
||||
if (do_bad144) {
|
||||
u_short cyl;
|
||||
u_short head;
|
||||
u_short sec;
|
||||
int newsec;
|
||||
struct disklabel *dl = &disklabel;
|
||||
|
||||
/* XXX */
|
||||
/* from wd.c */
|
||||
/* bt_cyl = cylinder number in sorted order */
|
||||
/* bt_trksec is actually (head << 8) + sec */
|
||||
|
||||
/* only remap sectors in the partition */
|
||||
if (sector < boff || sector >= boff + bsize) {
|
||||
goto no_remap;
|
||||
}
|
||||
|
||||
cyl = (sector-boff) / dl->d_secpercyl;
|
||||
head = ((sector-boff) % dl->d_secpercyl) / dl->d_nsectors;
|
||||
sec = (sector-boff) % dl->d_nsectors;
|
||||
sec = (head<<8) + sec;
|
||||
|
||||
/* now, look in the table for a possible bad sector */
|
||||
for (i=0; i<126; i++) {
|
||||
if (dkb.bt_bad[i].bt_cyl == cyl) {
|
||||
/* found same cylinder */
|
||||
if (dkb.bt_bad[i].bt_trksec == sec) {
|
||||
/* FOUND! */
|
||||
break;
|
||||
}
|
||||
} else if (dkb.bt_bad[i].bt_cyl > cyl) {
|
||||
i = 126;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 126) {
|
||||
/* didn't find bad sector */
|
||||
goto no_remap;
|
||||
}
|
||||
/* otherwise find replacement sector */
|
||||
if (dl->d_partitions[BSD_PART].p_offset != 0)
|
||||
newsec = dl->d_partitions[BAD144_PART].p_offset
|
||||
+ dl->d_partitions[BAD144_PART].p_size;
|
||||
else
|
||||
newsec = dl->d_secperunit;
|
||||
newsec -= dl->d_nsectors + i + 1;
|
||||
return newsec;
|
||||
}
|
||||
no_remap:
|
||||
#endif
|
||||
return sector;
|
||||
}
|
429
sys/boot/pc98/boot2/io.c
Normal file
429
sys/boot/pc98/boot2/io.c
Normal file
@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
|
||||
* $Id: io.c,v 1.13 1997/12/05 11:50:42 kato Exp $
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
#include <machine/cpufunc.h>
|
||||
#include <sys/reboot.h>
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#endif
|
||||
|
||||
|
||||
static int getchar(int in_buf);
|
||||
|
||||
/*
|
||||
* Gate A20 for high memory
|
||||
*/
|
||||
void
|
||||
gateA20(void)
|
||||
{
|
||||
outb(0xf2, 0x00);
|
||||
outb(0xf6, 0x02);
|
||||
}
|
||||
|
||||
/* printf - only handles %d as decimal, %c as char, %s as string */
|
||||
|
||||
void
|
||||
printf(const char *format, ...)
|
||||
{
|
||||
int *dataptr = (int *)&format;
|
||||
char c;
|
||||
|
||||
dataptr++;
|
||||
while ((c = *format++))
|
||||
if (c != '%')
|
||||
putchar(c);
|
||||
else
|
||||
switch (c = *format++) {
|
||||
case 'd': {
|
||||
int num = *dataptr++;
|
||||
char buf[10], *ptr = buf;
|
||||
if (num<0) {
|
||||
num = -num;
|
||||
putchar('-');
|
||||
}
|
||||
do
|
||||
*ptr++ = '0'+num%10;
|
||||
while (num /= 10);
|
||||
do
|
||||
putchar(*--ptr);
|
||||
while (ptr != buf);
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
unsigned int num = *dataptr++, dig;
|
||||
char buf[8], *ptr = buf;
|
||||
do
|
||||
*ptr++ = (dig=(num&0xf)) > 9?
|
||||
'a' + dig - 10 :
|
||||
'0' + dig;
|
||||
while (num >>= 4);
|
||||
do
|
||||
putchar(*--ptr);
|
||||
while (ptr != buf);
|
||||
break;
|
||||
}
|
||||
case 'c': putchar((*dataptr++)&0xff); break;
|
||||
case 's': {
|
||||
char *ptr = (char *)*dataptr++;
|
||||
while ((c = *ptr++))
|
||||
putchar(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
putchar(int c)
|
||||
{
|
||||
if (c == '\n')
|
||||
putchar('\r');
|
||||
if (loadflags & RB_DUAL) {
|
||||
putc(c);
|
||||
serial_putc(c);
|
||||
} else if (loadflags & RB_SERIAL)
|
||||
serial_putc(c);
|
||||
else
|
||||
putc(c);
|
||||
}
|
||||
|
||||
static int
|
||||
getchar(int in_buf)
|
||||
{
|
||||
int c;
|
||||
|
||||
loop:
|
||||
if (loadflags & RB_DUAL) {
|
||||
if (ischar())
|
||||
c = getc();
|
||||
else if (serial_ischar())
|
||||
c = serial_getc();
|
||||
else
|
||||
goto loop;
|
||||
} else if (loadflags & RB_SERIAL)
|
||||
c = serial_getc();
|
||||
else
|
||||
c = getc();
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
if (c == '\b') {
|
||||
if (in_buf != 0) {
|
||||
putchar('\b');
|
||||
putchar(' ');
|
||||
} else {
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
putchar(c);
|
||||
return(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine uses an inb to an unused port, the time to execute that
|
||||
* inb is approximately 1.25uS. This value is pretty constant across
|
||||
* all CPU's and all buses, with the exception of some PCI implentations
|
||||
* that do not forward this I/O adress to the ISA bus as they know it
|
||||
* is not a valid ISA bus address, those machines execute this inb in
|
||||
* 60 nS :-(.
|
||||
*
|
||||
* XXX this should be converted to use bios_tick.
|
||||
*/
|
||||
void
|
||||
delay1ms(void)
|
||||
{
|
||||
#ifdef PC98
|
||||
int i = 800;
|
||||
while (--i >= 0)
|
||||
(void)outb(0x5f,0); /* about 600ns */
|
||||
#else
|
||||
int i = 800;
|
||||
while (--i >= 0)
|
||||
(void)inb(0x84);
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline int
|
||||
isch(void)
|
||||
{
|
||||
int isc;
|
||||
|
||||
/*
|
||||
* Checking the keyboard has the side effect of enabling clock
|
||||
* interrupts so that bios_tick works. Check the keyboard to
|
||||
* get this side effect even if we only want the serial status.
|
||||
*/
|
||||
isc = ischar();
|
||||
|
||||
if (loadflags & RB_DUAL) {
|
||||
if (isc != 0)
|
||||
return (isc);
|
||||
} else if (!(loadflags & RB_SERIAL))
|
||||
return (isc);
|
||||
return (serial_ischar());
|
||||
}
|
||||
|
||||
static __inline unsigned
|
||||
pword(unsigned physaddr)
|
||||
{
|
||||
#ifdef PC98
|
||||
static int counter = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 512; i++)
|
||||
(void)outb(0x5f, 0);
|
||||
|
||||
return (counter++);
|
||||
#else
|
||||
unsigned result;
|
||||
|
||||
/*
|
||||
* Give the fs prefix separately because gas omits it for
|
||||
* "movl %fs:0x46c, %eax".
|
||||
*/
|
||||
__asm __volatile("fs; movl %1, %0" : "=r" (result)
|
||||
: "m" (*(unsigned *)physaddr));
|
||||
return (result);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
gets(char *buf)
|
||||
{
|
||||
#define bios_tick pword(0x46c)
|
||||
#ifdef PC98
|
||||
#define BIOS_TICK_MS 1
|
||||
#else
|
||||
#define BIOS_TICK_MS 55
|
||||
#endif
|
||||
unsigned initial_bios_tick;
|
||||
char *ptr=buf;
|
||||
|
||||
#if BOOTWAIT
|
||||
for (initial_bios_tick = bios_tick;
|
||||
bios_tick - initial_bios_tick < BOOTWAIT / BIOS_TICK_MS;)
|
||||
#endif
|
||||
if (isch())
|
||||
for (;;) {
|
||||
switch(*ptr = getchar(ptr - buf) & 0xff) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
*ptr = '\0';
|
||||
return 1;
|
||||
case '\b':
|
||||
if (ptr > buf) ptr--;
|
||||
continue;
|
||||
default:
|
||||
ptr++;
|
||||
}
|
||||
#if TIMEOUT + 0
|
||||
#if !BOOTWAIT
|
||||
#error "TIMEOUT without BOOTWAIT"
|
||||
#endif
|
||||
for (initial_bios_tick = bios_tick;;) {
|
||||
if (isch())
|
||||
break;
|
||||
if (bios_tick - initial_bios_tick >=
|
||||
TIMEOUT / BIOS_TICK_MS)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 == *s2) {
|
||||
if (!*s1++)
|
||||
return 0;
|
||||
s2++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CDBOOT
|
||||
int
|
||||
strcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
/*
|
||||
* We only consider ASCII chars and don't anticipate
|
||||
* control characters (they are invalid in filenames
|
||||
* anyway).
|
||||
*/
|
||||
while ((*s1 & 0x5f) == (*s2 & 0x5f)) {
|
||||
if (!*s1++)
|
||||
return 0;
|
||||
s2++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* !CDBOOT */
|
||||
|
||||
void
|
||||
bcopy(const void *from, void *to, size_t len)
|
||||
{
|
||||
char *fp = (char *)from;
|
||||
char *tp = (char *)to;
|
||||
|
||||
while (len-- > 0)
|
||||
*tp++ = *fp++;
|
||||
}
|
||||
|
||||
/* To quote Ken: "You are not expected to understand this." :) */
|
||||
|
||||
void
|
||||
twiddle(void)
|
||||
{
|
||||
putchar((char)tw_chars);
|
||||
tw_chars = (tw_chars >> 8) | ((tw_chars & (unsigned long)0xFF) << 24);
|
||||
putchar('\b');
|
||||
}
|
||||
|
||||
static unsigned short *Crtat = (unsigned short *)0;
|
||||
static int row;
|
||||
static int col;
|
||||
|
||||
void putc(int c)
|
||||
{
|
||||
static unsigned short *crtat;
|
||||
unsigned char sys_type;
|
||||
unsigned short *cp;
|
||||
int i, pos;
|
||||
|
||||
if (Crtat == 0) {
|
||||
sys_type = *(unsigned char *)V(0xA1501);
|
||||
if (sys_type & 0x08) {
|
||||
Crtat = (unsigned short *)V(0xE0000);
|
||||
crtat = Crtat;
|
||||
row = 31;
|
||||
col = 80;
|
||||
} else {
|
||||
Crtat = (unsigned short *)V(0xA0000);
|
||||
crtat = Crtat;
|
||||
row = 25;
|
||||
col = 80;
|
||||
}
|
||||
}
|
||||
|
||||
switch(c) {
|
||||
case '\t':
|
||||
do {
|
||||
putc(' ');
|
||||
} while ((int)crtat % 16);
|
||||
break;
|
||||
case '\b':
|
||||
crtat--;
|
||||
break;
|
||||
case '\r':
|
||||
crtat -= (crtat - Crtat) % col;
|
||||
break;
|
||||
case '\n':
|
||||
crtat += col;
|
||||
break;
|
||||
default:
|
||||
*crtat = (c == 0x5c ? 0xfc : c);
|
||||
*(crtat++ + 0x1000) = 0xe1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (crtat >= Crtat + col * row) {
|
||||
cp = Crtat;
|
||||
for (i = 1; i < row; i++) {
|
||||
bcopy((void *)(cp+col), (void *)cp, col*2);
|
||||
cp += col;
|
||||
}
|
||||
for (i = 0; i < col; i++) {
|
||||
*cp++ = ' ';
|
||||
}
|
||||
crtat -= col;
|
||||
}
|
||||
pos = crtat - Crtat;
|
||||
while((inb(0x60) & 0x04) == 0) {}
|
||||
outb(0x62, 0x49);
|
||||
outb(0x60, pos & 0xff);
|
||||
outb(0x60, pos >> 8);
|
||||
}
|
||||
|
||||
void machine_check(void)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
int data = 0;
|
||||
u_char epson_machine_id = *(unsigned char *)V(0xA1624);
|
||||
|
||||
/* PC98_SYSTEM_PARAMETER(0x501) */
|
||||
ret = ((*(unsigned char*)V(0xA1501)) & 0x08) >> 3;
|
||||
|
||||
/* Wait V-SYNC */
|
||||
while (inb(0x60) & 0x20) {}
|
||||
while (!(inb(0x60) & 0x20)) {}
|
||||
|
||||
/* ANK 'A' font */
|
||||
outb(0xa1, 0x00);
|
||||
outb(0xa3, 0x41);
|
||||
|
||||
/* M_NORMAL, use CG window (all NEC OK) */
|
||||
/* sum */
|
||||
for (i = 0; i < 4; i++) {
|
||||
data += *((unsigned long*)V(0xA4000) + i);/* 0xa4000 */
|
||||
}
|
||||
if (data == 0x6efc58fc) { /* DA data */
|
||||
ret |= M_NEC_PC98;
|
||||
} else {
|
||||
ret |= M_EPSON_PC98;
|
||||
}
|
||||
ret |= (inb(0x42) & 0x20) ? M_8M : 0;
|
||||
|
||||
/* PC98_SYSTEM_PARAMETER(0x400) */
|
||||
if ((*(unsigned char*)V(0xA1400)) & 0x80) {
|
||||
ret |= M_NOTE;
|
||||
}
|
||||
if (ret & M_NEC_PC98) {
|
||||
/* PC98_SYSTEM_PARAMETER(0x458) */
|
||||
if ((*(unsigned char*)V(0xA1458)) & 0x80) {
|
||||
ret |= M_H98;
|
||||
} else {
|
||||
ret |= M_NOT_H98;
|
||||
}
|
||||
} else {
|
||||
ret |= M_NOT_H98;
|
||||
switch (epson_machine_id) {
|
||||
case 0x20: /* note A */
|
||||
case 0x22: /* note W */
|
||||
case 0x27: /* note AE */
|
||||
case 0x2a: /* note WR */
|
||||
ret |= M_NOTE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
(*(unsigned long *)V(0xA1620)) = ret;
|
||||
}
|
39
sys/boot/pc98/boot2/probe_keyboard.c
Normal file
39
sys/boot/pc98/boot2/probe_keyboard.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) KATO Takenori, 1994-1995. 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 as
|
||||
* the first lines of this file unmodified.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
|
||||
int probe_keyboard(void)
|
||||
{
|
||||
/*
|
||||
* New type (RA and later) keyboard only!
|
||||
*/
|
||||
if (*(unsigned char*)V(0xA1481) & 0x48)
|
||||
return 0;
|
||||
return 1; /* keyboard not found */
|
||||
}
|
||||
|
201
sys/boot/pc98/boot2/serial.S
Normal file
201
sys/boot/pc98/boot2/serial.S
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
|
||||
* $Id: serial.S,v 1.8 1999/01/03 05:03:46 kato Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Serial bootblock interface routines
|
||||
* Copyright (c) 1994, J"org Wunsch
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if COMCONSOLE == 0x238
|
||||
#include "../../../i386/boot/biosboot/serial.S"
|
||||
#else
|
||||
/*
|
||||
* modified for PC-98 by KATO T. of Nagoya University
|
||||
*/
|
||||
|
||||
.file "serial.S"
|
||||
|
||||
#include <i386/isa/sioreg.h>
|
||||
#include "asm.h"
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* The serial port interface routines implement a simple polled i/o
|
||||
* interface to a standard serial port. Due to the space restrictions
|
||||
* for the boot blocks, no BIOS support is used (since BIOS requires
|
||||
* expensive real/protected mode switches), instead the rudimentary
|
||||
* BIOS support is duplicated here.
|
||||
*
|
||||
* The base address for the i/o port is passed from the Makefile in
|
||||
* the COMCONSOLE preprocessor macro. Console parameters are currently
|
||||
* hard-coded to 9600 Bd, 8 bit. This can be changed in the
|
||||
* init_serial() function.
|
||||
*/
|
||||
|
||||
/*
|
||||
* void serial_putc(char ch)
|
||||
* send ch to serial port
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(serial_putc)
|
||||
mov $COMCONSOLE + 2, %edx # line status reg
|
||||
1: inb %dx, %al
|
||||
testb $0x01, %al
|
||||
jz 1b # TX buffer not empty
|
||||
|
||||
movb 0x4(%esp), %al
|
||||
|
||||
sub $2, %edx # TX output reg
|
||||
outb %al, %dx # send this one
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* int serial_getc(void)
|
||||
* read a character from serial port
|
||||
*/
|
||||
|
||||
ENTRY(serial_getc)
|
||||
mov $COMCONSOLE + 2, %edx # line status reg
|
||||
1:
|
||||
inb %dx, %al
|
||||
testb $0x02, %al
|
||||
jz 1b # no RX char available
|
||||
|
||||
xorb %eax, %eax
|
||||
subb $2, %edx # RX buffer reg
|
||||
inb %dx, %al # fetch (first) character
|
||||
|
||||
cmp $0x7F, %eax # make DEL...
|
||||
jne 2f
|
||||
movb $0x08, %eax # look like BS
|
||||
2:
|
||||
ret
|
||||
|
||||
/*
|
||||
* int serial_ischar(void)
|
||||
* if there is a character pending, return true; otherwise return 0
|
||||
*/
|
||||
ENTRY(serial_ischar)
|
||||
xorl %eax, %eax
|
||||
movl $COMCONSOLE + 2, %edx # line status reg
|
||||
inb %dx, %al
|
||||
andb $0x02, %al # RX char available?
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* void init_serial(void)
|
||||
* initialize the serial console port to 9600 Bd, 8 bpc
|
||||
*/
|
||||
ENTRY(init_serial)
|
||||
/* set 8253 */
|
||||
movb 0xb6, %al
|
||||
outb %al, $0x77
|
||||
movl $COMCONSOLE_CLK, %eax
|
||||
outb %al, $0x75
|
||||
inb $0x5f, %al
|
||||
movb %ah, %al
|
||||
outb %al, $0x75
|
||||
|
||||
/* inhibit com int */
|
||||
inb $0x35, %al
|
||||
andb $0xf8, %al
|
||||
movb %al, %ah
|
||||
inb $0x5f, %al
|
||||
movb %ah, %al
|
||||
outb %al, $0x35
|
||||
|
||||
inb $0x02, %al
|
||||
orb $0x10, %al
|
||||
outb %al, $0x02
|
||||
|
||||
/* dummy command */
|
||||
xorb %al,%al
|
||||
movl $COMCONSOLE + 2, %edx
|
||||
outb %al, %dx
|
||||
inb $0x5f, %al
|
||||
xorb %al,%al
|
||||
outb %al, %dx
|
||||
inb $0x5f, %al
|
||||
xorb %al,%al
|
||||
outb %al, %dx
|
||||
inb $0x5f, %al
|
||||
|
||||
/* RESET 8251 */
|
||||
movb $0x40, %al
|
||||
outb %al, %dx
|
||||
|
||||
movb $COMCONSOLE_MODE , %al
|
||||
andb $0xfc, %al
|
||||
orb $0x02, %al /* factor = 1/16 */
|
||||
outb %al, %dx
|
||||
inb $0x5f, %al
|
||||
|
||||
/* start RS-232C */
|
||||
movb $0x37, %al
|
||||
outb %al, %dx
|
||||
|
||||
ret
|
||||
#endif
|
535
sys/boot/pc98/boot2/start.S
Normal file
535
sys/boot/pc98/boot2/start.S
Normal file
@ -0,0 +1,535 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:36:29 rpd
|
||||
* $Id: start.S,v 1.6 1998/07/30 02:27:41 alex Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
/*
|
||||
* Ported to PC-9801 by Yoshio Kimura
|
||||
*/
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
.file "start.S"
|
||||
|
||||
SIGNATURE= 0xaa55
|
||||
LOADSZ= 8192 /* size of unix boot */
|
||||
|
||||
NAMEBLOCKMAGIC= 0xfadefeed /* value of magicnumebr for block2 */
|
||||
|
||||
/*
|
||||
* This DEBUGMSG(msg) macro may be useful for debugging. Its use is
|
||||
* restricted to this file since it only works in real mode.
|
||||
*/
|
||||
#define DEBUGMSG(msg) \
|
||||
data32 ; \
|
||||
mov $msg, %esi ; \
|
||||
data32 ; \
|
||||
call message
|
||||
|
||||
.text
|
||||
.globl start
|
||||
|
||||
ENTRY(boot1)
|
||||
jmp start
|
||||
|
||||
boot_cyl:
|
||||
.word 0
|
||||
String "IPL1 "
|
||||
|
||||
start:
|
||||
/* set up %ds */
|
||||
xor %ax, %ax
|
||||
mov %ax, %ds
|
||||
|
||||
/* set up %ss and %esp */
|
||||
data32
|
||||
mov $BOOTSEG, %eax
|
||||
mov %ax, %ss
|
||||
/*
|
||||
* make a little room on the stack for
|
||||
* us to save the default bootstring we might find..
|
||||
* effectively, we push the bootstring.
|
||||
*/
|
||||
data32
|
||||
mov $BOOTSTACK-64, %esp
|
||||
|
||||
/* set up %es, (where we will load boot2 to) */
|
||||
mov %ax, %es
|
||||
|
||||
push %es
|
||||
push %cx
|
||||
push %dx
|
||||
|
||||
data32
|
||||
mov $0xa000, %eax
|
||||
mov %ax, %es
|
||||
|
||||
addr32
|
||||
movb 0x501, %al
|
||||
testb $0x08, %al
|
||||
jnz hireso
|
||||
normal:
|
||||
/* set up graphic screen */
|
||||
movb $0x42, %ah
|
||||
movb $0xc0, %ch
|
||||
int $0x18
|
||||
movb $0x40, %ah
|
||||
int $0x18
|
||||
|
||||
data32
|
||||
mov $0x0a00, %eax /* 80 x 25 mode */
|
||||
jmp 1f
|
||||
hireso:
|
||||
movb $0x08, %al /* set up RAM window */
|
||||
outb %al, $0x91
|
||||
movb $0x0a, %al
|
||||
outb %al, $0x93
|
||||
data32
|
||||
mov $0x0a10, %ax /* 80 x 31 mode */
|
||||
1:
|
||||
int $0x18
|
||||
movb $0x0c, %ah /* text on */
|
||||
int $0x18
|
||||
|
||||
/* cursor home and on */
|
||||
xor %edx, %edx
|
||||
movb $0x13, %ah
|
||||
int $0x18
|
||||
movb $0x11, %ah
|
||||
int $0x18
|
||||
|
||||
/* highreso no supported */
|
||||
addr32
|
||||
movb 0x501, %al
|
||||
testb $0x08, %al
|
||||
jz nothireso
|
||||
|
||||
data32
|
||||
mov $ehireso, %esi
|
||||
data32
|
||||
call message
|
||||
hlt
|
||||
|
||||
nothireso:
|
||||
/* keyboad reset */
|
||||
movb $0x03, %ah
|
||||
int $0x18
|
||||
|
||||
/* transfer PC-9801 system common area to 0xa1000 */
|
||||
data32
|
||||
mov $0x0000, %esi
|
||||
data32
|
||||
mov $0x1000, %edi
|
||||
data32
|
||||
mov $0x0630, %ecx
|
||||
cld
|
||||
rep
|
||||
movsb
|
||||
|
||||
/* transfer EPSON machine type to 0xa1200 */
|
||||
push %ds
|
||||
data32
|
||||
mov $0xfd00, %eax
|
||||
mov %ax, %ds
|
||||
addr32
|
||||
data32
|
||||
mov 0x804, %eax
|
||||
data32
|
||||
and $0x00ffffff, %eax
|
||||
addr32
|
||||
data32
|
||||
.byte 0x26
|
||||
mov %eax, %es: (0x1624)
|
||||
|
||||
pop %ds
|
||||
pop %dx
|
||||
pop %cx
|
||||
pop %es
|
||||
|
||||
/* bootstrap passes */
|
||||
mov %cs, %bx
|
||||
data32
|
||||
cmp $0x1fe0, %ebx
|
||||
jz fd
|
||||
data32
|
||||
cmp $0x1fc0, %ebx
|
||||
jnz hd
|
||||
data32
|
||||
mov %ebp, %ecx
|
||||
data32
|
||||
mov %ebp, %edx
|
||||
addr32
|
||||
movb 0x584, %al
|
||||
andb $0xf0, %al
|
||||
cmpb $0x30, %al
|
||||
jz fd
|
||||
cmpb $0x90, %al
|
||||
jnz hd
|
||||
fd:
|
||||
data32
|
||||
mov $0x0200, %ecx
|
||||
data32
|
||||
mov $0x0001, %edx
|
||||
movb $0xd6, %ah
|
||||
jmp load
|
||||
hd:
|
||||
data32
|
||||
and %ecx, %ecx
|
||||
jnz 1f
|
||||
addr32
|
||||
data32
|
||||
mov %cs: (boot_cyl), %ecx
|
||||
1:
|
||||
movb $0x06, %ah
|
||||
|
||||
/*
|
||||
* BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
|
||||
* Call with %ah = 0xd6(for floppy disk) or 0x06(for hard disk)
|
||||
* %al = DA/UA
|
||||
* %bx = data length
|
||||
* %ch = sector size(for floppy) or cylinder(for hard)
|
||||
* %cl = cylinder
|
||||
* %dh = head
|
||||
* %dl = sector
|
||||
* %es:%bp = segment:offset of buffer
|
||||
* Return:
|
||||
* %ah = 0x0 on success; err code on failure
|
||||
*/
|
||||
|
||||
load:
|
||||
#ifdef NAMEBLOCK
|
||||
/*
|
||||
* Load the second sector and see if it is a boot instruction block.
|
||||
* If it is then scan the contents for the first valid string and copy it to
|
||||
* the location of the default boot string.. then zero it out.
|
||||
* Finally write the block back to disk with the zero'd out entry..
|
||||
* I hate writing at this stage but we need this to be persistant.
|
||||
* If the boot fails, then the next boot will get the next string.
|
||||
* /etc/rc will regenerate a complete block2 iff the boot succeeds.
|
||||
*
|
||||
* Format of block 2 is:
|
||||
* [NAMEBLOCKMAGIC] <--0xdeafc0de
|
||||
* [nulls]
|
||||
* [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.experimental
|
||||
* [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.old
|
||||
* ....
|
||||
* [bootstring]NULL <---e.g. 0:wd(0,f)/kernel
|
||||
* FF FF FF
|
||||
*/
|
||||
where:
|
||||
/*
|
||||
* save things we might smash
|
||||
* (that are not smashed immedatly after us anyway.)
|
||||
*/
|
||||
data32
|
||||
push %ecx /* preserve 'cyl,sector ' */
|
||||
data32
|
||||
push %edx
|
||||
/*
|
||||
* Load the second sector
|
||||
* 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
|
||||
*/
|
||||
data32
|
||||
movl $0x0201, %eax /function 2 (read) 1 sector */
|
||||
xor %ebx, %ebx /* %bx = 0 */ /* buffer address (ES:0) */
|
||||
data32
|
||||
movl $0x0002, %ecx /* sector 2, cylinder 0 */
|
||||
data32
|
||||
andl $0x00ff, %edx /* head 0, drive N */
|
||||
int $0x13
|
||||
data32
|
||||
jb read_error
|
||||
/*
|
||||
* confirm that it is one for us
|
||||
*/
|
||||
data32
|
||||
xorl %ebx, %ebx /* magic number at start of buffer */
|
||||
data32
|
||||
addr32
|
||||
movl %es:(%ebx), %eax
|
||||
data32
|
||||
cmpl $NAMEBLOCKMAGIC, %eax
|
||||
data32
|
||||
jne notours /* not ours so return to caller */
|
||||
/*
|
||||
* scan for a bootstring
|
||||
* Skip the magic number, and scan till we find a non-null,
|
||||
* or a -1
|
||||
*/
|
||||
incl %ebx /* quicker and smaller */
|
||||
incl %ebx
|
||||
incl %ebx
|
||||
scan:
|
||||
incl %ebx
|
||||
addr32
|
||||
movb %es:(%ebx), %al /* load the next byte */
|
||||
testb %al, %al /* and if it is null */
|
||||
data32 /* keep scanning (past deleted entries) */
|
||||
jz scan
|
||||
incb %al /* now look for -1 */
|
||||
data32
|
||||
jz notours /* if we reach the 0xFF then we have finished */
|
||||
|
||||
/*
|
||||
* save our settings.. we need them twice..
|
||||
*/
|
||||
data32
|
||||
push %ebx
|
||||
/*
|
||||
* copy it to the default string location
|
||||
* which is just above the stack for 64 bytes.
|
||||
*/
|
||||
data32
|
||||
movl $BOOTSTACK-64, %ecx /* 64 bytes at the top of the stack */
|
||||
nxtbyte:
|
||||
addr32
|
||||
movb %es:(%ebx), %al /* get the next byte in */
|
||||
addr32
|
||||
movb %al, %es:(%ecx) /* and transfer it to the name buffer */
|
||||
incl %ebx /* get on with the next byte */
|
||||
incl %ecx /* get on with the next byte */
|
||||
testb %al, %al /* if it was 0 then quit this */
|
||||
data32
|
||||
jnz nxtbyte /* and looop if more to do */
|
||||
|
||||
/*
|
||||
* restore the saved settings and
|
||||
* zero it out so next time we don't try it again
|
||||
*/
|
||||
data32
|
||||
pop %ebx /* get back our starting location */
|
||||
#ifdef NAMEBLOCK_WRITEBACK
|
||||
nxtbyte2:
|
||||
addr32
|
||||
movb %es:(%ebx), %al /* get the byte */
|
||||
addr32
|
||||
movb $0, %es:(%ebx) /* zero it out */
|
||||
data32
|
||||
incl %ebx /* point to the next byte */
|
||||
testb %al, %al /* check if we have finished.. */
|
||||
data32
|
||||
jne nxtbyte2
|
||||
/*
|
||||
* Write the second sector back
|
||||
* Load the second sector
|
||||
* BIOS call "INT 0x13 Function 0x3" to write sectors from memory to disk
|
||||
* Call with %ah = 0x3
|
||||
* %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
|
||||
*/
|
||||
data32
|
||||
movl $0x0301, %eax /* write 1 sector */
|
||||
xor %ebx, %ebx /* buffer is at offset 0 */
|
||||
data32
|
||||
movl $0x0002, %ecx /* block 2 */
|
||||
data32
|
||||
andl $0xff, %edx /* head 0 */
|
||||
int $0x13
|
||||
data32
|
||||
jnb notours
|
||||
data32
|
||||
mov $eread, %esi
|
||||
jmp err_stop
|
||||
#endif /* NAMEBLOCK_WRITEBACK */
|
||||
/*
|
||||
* return to the main-line
|
||||
*/
|
||||
notours:
|
||||
data32
|
||||
pop %edx
|
||||
data32
|
||||
pop %ecx
|
||||
#endif
|
||||
data32
|
||||
mov $LOADSZ, %ebx
|
||||
addr32
|
||||
movb 0x584, %al
|
||||
xor %ebp, %ebp /* %bp = 0, put it at 0 in the BOOTSEG */
|
||||
int $0x1b
|
||||
jc read_error
|
||||
|
||||
/*
|
||||
* ljmp to the second stage boot loader (boot2).
|
||||
* After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
|
||||
* as an internal buffer "intbuf".
|
||||
*/
|
||||
|
||||
data32
|
||||
ljmp $BOOTSEG, $ EXT(boot2)
|
||||
|
||||
/*
|
||||
* read_error
|
||||
*/
|
||||
read_error:
|
||||
data32
|
||||
mov $eread, %esi
|
||||
err_stop:
|
||||
data32
|
||||
call message
|
||||
data32
|
||||
jmp stop
|
||||
|
||||
/*
|
||||
* message: write the error message in %ds:%esi to console
|
||||
*/
|
||||
message:
|
||||
|
||||
data32
|
||||
push %eax
|
||||
data32
|
||||
push %ebx
|
||||
push %ds
|
||||
push %es
|
||||
data32
|
||||
mov $0xe000, %eax
|
||||
mov %ax, %es
|
||||
addr32
|
||||
mov 0x501, %al
|
||||
testb $0x08, %al
|
||||
jnz 1f
|
||||
data32
|
||||
mov $0xa000, %eax
|
||||
mov %ax, %es
|
||||
1:
|
||||
mov %cs, %ax
|
||||
mov %ax, %ds
|
||||
addr32
|
||||
data32
|
||||
mov vram, %edi
|
||||
data32
|
||||
mov $0x00e1, %ebx
|
||||
cld
|
||||
|
||||
nextb:
|
||||
lodsb /* load a byte into %al */
|
||||
cmpb $0x0, %al
|
||||
je done
|
||||
cmpb $0x0d, %al
|
||||
je cr_code
|
||||
cmpb $0x0a, %al
|
||||
je lf_code
|
||||
addr32
|
||||
movb %al, (%edi)
|
||||
addr32
|
||||
movb %bl, 0x2000(%edi)
|
||||
data32
|
||||
inc %edi
|
||||
data32
|
||||
inc %edi
|
||||
jmp nextb
|
||||
cr_code:
|
||||
data32
|
||||
add $80, %edi
|
||||
jmp nextb
|
||||
lf_code:
|
||||
data32
|
||||
mov %edi, %eax
|
||||
data32
|
||||
mov $80, %edx
|
||||
data32
|
||||
div %ebx
|
||||
data32
|
||||
sub %ebx, %edi
|
||||
jmp nextb
|
||||
done:
|
||||
addr32
|
||||
data32
|
||||
mov %edi, vram
|
||||
pop %es
|
||||
pop %ds
|
||||
data32
|
||||
pop %ebx
|
||||
data32
|
||||
pop %eax
|
||||
data32
|
||||
ret
|
||||
|
||||
stop: hlt
|
||||
data32
|
||||
jmp stop /* halt doesnt actually halt forever */
|
||||
|
||||
vram:
|
||||
.long 0
|
||||
|
||||
/* error messages */
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
one: String "1-\0"
|
||||
two: String "2-\0"
|
||||
three: String "3-\0"
|
||||
four: String "4-\0"
|
||||
#endif DEBUG
|
||||
#ifdef NAMEBLOCK_WRITEBACK
|
||||
ewrite: String "Write error\r\n\0"
|
||||
#endif /* NAMEBLOCK_WRITEBACK */
|
||||
eread: String "Read error\r\n\0"
|
||||
enoboot: String "No bootable partition\r\n\0"
|
||||
endofcode:
|
||||
ehireso: String "Highreso not supported\r\n\0"
|
||||
/* the last 2 bytes in the sector 0 contain the signature */
|
||||
. = EXT(boot1) + 0x1fe
|
||||
.value SIGNATURE
|
||||
ENTRY(disklabel)
|
||||
. = EXT(boot1) + 0x400
|
337
sys/boot/pc98/boot2/sys.c
Normal file
337
sys/boot/pc98/boot2/sys.c
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:36:34 rpd
|
||||
* $Id: sys.c,v 1.15 1998/05/02 02:06:08 kato Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ported to PC-9801 by Yoshio Kimura
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#if 0
|
||||
/* #define BUFSIZE 4096 */
|
||||
#define BUFSIZE MAXBSIZE
|
||||
static char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
|
||||
#endif
|
||||
|
||||
static char biosdrivedigit;
|
||||
|
||||
#define BUFSIZE 8192
|
||||
#define MAPBUFSIZE BUFSIZE
|
||||
static char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
|
||||
|
||||
static char mapbuf[MAPBUFSIZE];
|
||||
static int mapblock;
|
||||
|
||||
int poff;
|
||||
|
||||
#ifdef RAWBOOT
|
||||
#define STARTBYTE 8192 /* Where on the media the kernel starts */
|
||||
#endif
|
||||
|
||||
static int block_map(int file_block);
|
||||
static int find(char *path);
|
||||
|
||||
void
|
||||
xread(char *addr, int size)
|
||||
{
|
||||
int count = BUFSIZE;
|
||||
while (size > 0) {
|
||||
if (BUFSIZE > size)
|
||||
count = size;
|
||||
read(buf, count);
|
||||
pcpy(buf, addr, count);
|
||||
size -= count;
|
||||
addr += count;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef RAWBOOT
|
||||
void
|
||||
read(char *buffer, int count)
|
||||
{
|
||||
int logno, off, size;
|
||||
int cnt2, bnum2;
|
||||
struct fs *fs_copy;
|
||||
|
||||
while (count > 0 && poff < inode.i_size) {
|
||||
fs_copy = fs;
|
||||
off = blkoff(fs_copy, poff);
|
||||
logno = lblkno(fs_copy, poff);
|
||||
cnt2 = size = blksize(fs_copy, &inode, logno);
|
||||
bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
|
||||
if ( (!off) && (size <= count)) {
|
||||
devread(buffer, bnum2, cnt2);
|
||||
} else {
|
||||
size -= off;
|
||||
if (size > count)
|
||||
size = count;
|
||||
devread(iobuf, bnum2, cnt2);
|
||||
bcopy(iobuf+off, buffer, size);
|
||||
}
|
||||
buffer += size;
|
||||
count -= size;
|
||||
poff += size;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void
|
||||
read(char *buffer, int count)
|
||||
{
|
||||
int cnt, bnum, off, size;
|
||||
|
||||
off = STARTBYTE + poff;
|
||||
poff += count;
|
||||
|
||||
/* Read any unaligned bit at the front */
|
||||
cnt = off & 511;
|
||||
if (cnt) {
|
||||
size = 512-cnt;
|
||||
if (count < size)
|
||||
size = count;
|
||||
devread(iobuf, off >> 9, 512);
|
||||
bcopy(iobuf+cnt, buffer, size);
|
||||
count -= size;
|
||||
off += size;
|
||||
buffer += size;
|
||||
}
|
||||
size = count & (~511);
|
||||
if (size && (off & (~511))) {
|
||||
devread(buffer, off >> 9, size);
|
||||
off += size;
|
||||
count -= size;
|
||||
buffer += size;
|
||||
}
|
||||
if (count) {
|
||||
devread(iobuf, off >> 9, 512);
|
||||
bcopy(iobuf, buffer, count);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
find(char *path)
|
||||
{
|
||||
char *rest, ch;
|
||||
int block, off, loc, ino = ROOTINO;
|
||||
struct dirent *dp;
|
||||
char list_only;
|
||||
|
||||
list_only = (path[0] == '?' && path[1] == '\0');
|
||||
loop:
|
||||
devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
|
||||
bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
|
||||
(void *)&inode.i_din,
|
||||
sizeof (struct dinode));
|
||||
if (!*path)
|
||||
return 1;
|
||||
while (*path == '/')
|
||||
path++;
|
||||
if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
|
||||
return 0;
|
||||
for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
|
||||
*rest = 0;
|
||||
loc = 0;
|
||||
do {
|
||||
if (loc >= inode.i_size) {
|
||||
if (list_only) {
|
||||
putchar('\n');
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!(off = blkoff(fs, loc))) {
|
||||
block = lblkno(fs, loc);
|
||||
devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
|
||||
blksize(fs, &inode, block));
|
||||
}
|
||||
dp = (struct dirent *)(iobuf + off);
|
||||
loc += dp->d_reclen;
|
||||
if (dp->d_fileno && list_only)
|
||||
printf("%s ", dp->d_name);
|
||||
} while (!dp->d_fileno || strcmp(path, dp->d_name));
|
||||
ino = dp->d_fileno;
|
||||
*(path = rest) = ch;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
block_map(int file_block)
|
||||
{
|
||||
int bnum;
|
||||
if (file_block < NDADDR)
|
||||
return(inode.i_db[file_block]);
|
||||
if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
|
||||
devread(mapbuf, bnum, fs->fs_bsize);
|
||||
mapblock = bnum;
|
||||
}
|
||||
return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
openrd(void)
|
||||
{
|
||||
char **devp, *name0 = name, *cp = name0;
|
||||
int biosdrive, dosdev_copy, ret;
|
||||
|
||||
/*******************************************************\
|
||||
* If bracket given look for preceding device name *
|
||||
\*******************************************************/
|
||||
while (*cp && *cp!='(')
|
||||
cp++;
|
||||
if (!*cp)
|
||||
{
|
||||
cp = name0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Look for a BIOS drive number (a leading digit followed
|
||||
* by a colon).
|
||||
*/
|
||||
biosdrivedigit = '\0';
|
||||
if (*(name0 + 1) == ':' && *name0 >= '0' && *name0 <= '9') {
|
||||
biosdrivedigit = *name0;
|
||||
name0 += 2;
|
||||
}
|
||||
|
||||
if (cp++ != name0)
|
||||
{
|
||||
for (devp = devs; *devp; devp++)
|
||||
if (name0[0] == (*devp)[0] &&
|
||||
name0[1] == (*devp)[1])
|
||||
break;
|
||||
if (!*devp)
|
||||
{
|
||||
printf("Unknown device\n");
|
||||
return 1;
|
||||
}
|
||||
maj = devp-devs;
|
||||
}
|
||||
/*******************************************************\
|
||||
* Look inside brackets for unit number, and partition *
|
||||
\*******************************************************/
|
||||
/*
|
||||
* Allow any valid digit as the unit number, as the BIOS
|
||||
* will complain if the unit number is out of range.
|
||||
* Restricting the range here prevents the possibilty of using
|
||||
* BIOSes that support more than 2 units.
|
||||
* XXX Bad values may cause strange errors, need to check if
|
||||
* what happens when a value out of range is supplied.
|
||||
*/
|
||||
if (*cp >= '0' && *cp <= '9')
|
||||
unit = *cp++ - '0';
|
||||
if (!*cp || (*cp == ',' && !*++cp))
|
||||
return 1;
|
||||
if (*cp >= 'a' && *cp <= 'p')
|
||||
part = *cp++ - 'a';
|
||||
while (*cp && *cp++!=')') ;
|
||||
if (!*cp)
|
||||
return 1;
|
||||
}
|
||||
biosdrive = biosdrivedigit - '0';
|
||||
if (biosdrivedigit == '\0') {
|
||||
#ifdef PC98
|
||||
biosdrive = dosdev & 0x0f;
|
||||
#else
|
||||
biosdrive = unit;
|
||||
#endif
|
||||
#if BOOT_HD_BIAS > 0
|
||||
/* XXX */
|
||||
if (maj == 4)
|
||||
biosdrive += BOOT_HD_BIAS;
|
||||
#endif
|
||||
}
|
||||
switch(maj)
|
||||
{
|
||||
#ifdef PC98
|
||||
case 4: /* sd */
|
||||
dosdev_copy = biosdrive | 0xa0;
|
||||
#else /* IBM-PC */
|
||||
case 0:
|
||||
case 4:
|
||||
dosdev_copy = biosdrive | 0x80;
|
||||
#endif
|
||||
break;
|
||||
#ifdef PC98
|
||||
case 0:
|
||||
case 2:
|
||||
dosdev_copy = (maj << 3) | unit | 0x80;
|
||||
#else
|
||||
case 2:
|
||||
dosdev_copy = biosdrive;
|
||||
#endif
|
||||
break;
|
||||
#ifdef PC98
|
||||
case 6:/* 1.44MB FD */
|
||||
dosdev_copy = (maj << 3) | unit;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("Unknown device\n");
|
||||
return 1;
|
||||
}
|
||||
dosdev = dosdev_copy;
|
||||
#if 0
|
||||
/* XXX this is useful, but misplaced. */
|
||||
printf("dosdev= %x, biosdrive = %d, unit = %d, maj = %d\n",
|
||||
dosdev_copy, biosdrive, unit, maj);
|
||||
#endif
|
||||
|
||||
/***********************************************\
|
||||
* Now we know the disk unit and part, *
|
||||
* Load disk info, (open the device) *
|
||||
\***********************************************/
|
||||
if (devopen())
|
||||
return 1;
|
||||
|
||||
#ifndef RAWBOOT
|
||||
/***********************************************\
|
||||
* Load Filesystem info (mount the device) *
|
||||
\***********************************************/
|
||||
devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
|
||||
/***********************************************\
|
||||
* Find the actual FILE on the mounted device *
|
||||
\***********************************************/
|
||||
ret = find(cp);
|
||||
name = cp;
|
||||
if (ret == 0)
|
||||
return 1;
|
||||
if (ret < 0) {
|
||||
name = NULL;
|
||||
return -1;
|
||||
}
|
||||
poff = 0;
|
||||
#endif /* RAWBOOT */
|
||||
return 0;
|
||||
}
|
149
sys/boot/pc98/boot2/table.c
Normal file
149
sys/boot/pc98/boot2/table.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992, 1991 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:36:43 rpd
|
||||
* $Id: table.c,v 1.8 1998/10/11 15:09:36 kato Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
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 "boot.h"
|
||||
|
||||
/* Segment Descriptor
|
||||
*
|
||||
* 31 24 19 16 7 0
|
||||
* ------------------------------------------------------------
|
||||
* | | |B| |A| | | |1|0|E|W|A| |
|
||||
* | BASE 31..24 |G|/|0|V| LIMIT |P|DPL| TYPE | BASE 23:16 |
|
||||
* | | |D| |L| 19..16| | |1|1|C|R|A| |
|
||||
* ------------------------------------------------------------
|
||||
* | | |
|
||||
* | BASE 15..0 | LIMIT 15..0 |
|
||||
* | | |
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
struct seg_desc {
|
||||
unsigned short limit_15_0;
|
||||
unsigned short base_15_0;
|
||||
unsigned char base_23_16;
|
||||
unsigned char p_dpl_type;
|
||||
unsigned char g_b_a_limit;
|
||||
unsigned char base_31_24;
|
||||
};
|
||||
|
||||
#define RUN 0 /* not really 0, but filled in at boot time */
|
||||
|
||||
struct seg_desc Gdt[] = {
|
||||
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 0x0 : null */
|
||||
{0xFFFF, 0x0, 0x0, 0x9F, 0xCF, 0x0}, /* 0x08 : kernel code */
|
||||
/* 0x9E? */
|
||||
{0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0}, /* 0x10 : kernel data */
|
||||
/* 0x92? */
|
||||
{0xFFFF, RUN, RUN, 0x9E, 0x40, 0x0}, /* 0x18 : boot code */
|
||||
#ifdef PC98
|
||||
/*
|
||||
* The limit of boot data should be more than or equal to 0x9FFFF
|
||||
* for saving BIOS parameter and EPSON machine ID into 2'nd T-VRAM,
|
||||
* because base address is normally 0x10000.
|
||||
*/
|
||||
{0xFFFF, RUN, RUN, 0x92, 0x4F, 0x0}, /* 0x20 : boot data */
|
||||
#else
|
||||
{0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* 0x20 : boot data */
|
||||
#endif
|
||||
{0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0}, /* 0x28 : boot code, 16 bits */
|
||||
{0xFFFF, 0x0, 0x0, 0x92, 0x0, 0x0}, /* 0x30 : boot data, 16 bits */
|
||||
#ifdef BDE_DEBUGGER
|
||||
/* More for bdb. */
|
||||
{}, /* BIOS_TMP_INDEX = 7 : null */
|
||||
{}, /* TSS_INDEX = 8 : null */
|
||||
{0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* DS_286_INDEX = 9 */
|
||||
{0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* ES_286_INDEX = 10 */
|
||||
{}, /* Unused = 11 : null */
|
||||
{0x7FFF, 0x8000, 0xB, 0xB2, 0x40, 0x0}, /* COLOR_INDEX = 12 */
|
||||
{0x7FFF, 0x0, 0xB, 0xB2, 0x40, 0x0}, /* MONO_INDEX = 13 */
|
||||
{0xFFFF, RUN, RUN, 0x9A, 0x40, 0x0}, /* DB_CS_INDEX = 14 */
|
||||
{0xFFFF, RUN, RUN, 0x9A, 0x0, 0x0}, /* DB_CS16_INDEX = 15 */
|
||||
{0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* DB_DS_INDEX = 16 */
|
||||
{8*18-1, RUN, RUN, 0x92, 0x40, 0x0}, /* GDT_INDEX = 17 */
|
||||
#endif /* BDE_DEBUGGER */
|
||||
};
|
||||
|
||||
#ifdef BDE_DEBUGGER
|
||||
struct idt_desc {
|
||||
unsigned short entry_15_0;
|
||||
unsigned short selector;
|
||||
unsigned char padding;
|
||||
unsigned char p_dpl_type;
|
||||
unsigned short entry_31_16;
|
||||
};
|
||||
|
||||
struct idt_desc Idt[] = {
|
||||
{}, /* Null (int 0) */
|
||||
{RUN, 0x70, 0, 0x8E, 0}, /* DEBUG_VECTOR = 1 */
|
||||
{}, /* Null (int 2) */
|
||||
{RUN, 0x70, 0, 0xEE, 0}, /* BREAKPOINT_VECTOR = 3 */
|
||||
};
|
||||
#endif /* BDE_DEBUGGER */
|
||||
|
||||
struct pseudo_desc {
|
||||
unsigned short limit;
|
||||
unsigned short base_low;
|
||||
unsigned short base_high;
|
||||
};
|
||||
|
||||
struct pseudo_desc Gdtr = { sizeof Gdt - 1, RUN, RUN };
|
||||
#ifdef BDE_DEBUGGER
|
||||
struct pseudo_desc Idtr_prot = { sizeof Idt - 1, RUN, RUN };
|
||||
struct pseudo_desc Idtr_real = { 0x400 - 1, 0x0, 0x0 };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* All initialized data is defined in one file to reduce space wastage from
|
||||
* fragmentation.
|
||||
*/
|
||||
char *devs[] = { "wd", "dk", "fd", "wt", "da", 0 };
|
||||
unsigned tw_chars = 0x5C2D2F7C; /* "\-/|" */
|
5
sys/boot/pc98/btx/Makefile
Normal file
5
sys/boot/pc98/btx/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $Id: Makefile,v 1.4 1998/09/17 23:52:03 msmith Exp $
|
||||
|
||||
SUBDIR= btx btxldr lib # client ldrtst
|
||||
|
||||
.include <bsd.subdir.mk>
|
25
sys/boot/pc98/btx/btx/Makefile
Normal file
25
sys/boot/pc98/btx/btx/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# $Id: Makefile,v 1.5 1998/10/13 18:29:18 rnordier Exp $
|
||||
|
||||
M4?= m4
|
||||
|
||||
ORG= 0x9000
|
||||
|
||||
AFLAGS+= --defsym PC98=1
|
||||
|
||||
all: btx
|
||||
|
||||
btx: btx.o
|
||||
.if ${OBJFORMAT} == aout
|
||||
${LD} -nostdlib -N -s -T ${ORG} -o btx.out btx.o
|
||||
dd if=btx.out of=${.TARGET} ibs=32 skip=1
|
||||
.else
|
||||
${LD} -N -e start -Ttext ${ORG} -o btx.out btx.o
|
||||
objcopy -S -O binary btx.out ${.TARGET}
|
||||
.endif
|
||||
|
||||
btx.o: btx.m4 btx.s
|
||||
(cd ${.CURDIR}; ${M4} btx.m4 btx.s) | ${AS} ${AFLAGS} -o ${.TARGET}
|
||||
|
||||
CLEANFILES+= btx btx.out btx.o
|
||||
|
||||
.include <bsd.prog.mk>
|
1071
sys/boot/pc98/btx/btx/btx.S
Normal file
1071
sys/boot/pc98/btx/btx/btx.S
Normal file
File diff suppressed because it is too large
Load Diff
59
sys/boot/pc98/btx/btx/btx.m4
Normal file
59
sys/boot/pc98/btx/btx/btx.m4
Normal file
@ -0,0 +1,59 @@
|
||||
#
|
||||
# Copyright (c) 1998 Robert Nordier
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms are freely
|
||||
# permitted provided that the above copyright notice and this
|
||||
# paragraph and the following disclaimer are duplicated in all
|
||||
# such forms.
|
||||
#
|
||||
# This software is provided "AS IS" and without any express or
|
||||
# implied warranties, including, without limitation, the implied
|
||||
# warranties of merchantability and fitness for a particular
|
||||
# purpose.
|
||||
#
|
||||
|
||||
# $Id: btx.m4,v 1.1.1.1 1998/09/12 04:29:23 rnordier Exp $
|
||||
|
||||
define(_al,0x0)dnl
|
||||
define(_cl,0x1)dnl
|
||||
define(_dl,0x2)dnl
|
||||
define(_bl,0x3)dnl
|
||||
define(_ah,0x4)dnl
|
||||
define(_ch,0x5)dnl
|
||||
define(_dh,0x6)dnl
|
||||
define(_bh,0x7)dnl
|
||||
|
||||
define(_ax,0x0)dnl
|
||||
define(_cx,0x1)dnl
|
||||
define(_dx,0x2)dnl
|
||||
define(_bx,0x3)dnl
|
||||
define(_sp,0x4)dnl
|
||||
define(_bp,0x5)dnl
|
||||
define(_si,0x6)dnl
|
||||
define(_di,0x7)dnl
|
||||
|
||||
define(_bx_si,0x0)dnl
|
||||
define(_bx_di,0x1)dnl
|
||||
define(_bp_si,0x2)dnl
|
||||
define(_bp_di,0x3)dnl
|
||||
define(_si_,0x4)dnl
|
||||
define(_di_,0x5)dnl
|
||||
define(_bp_,0x6)dnl
|
||||
define(_bx_,0x7)dnl
|
||||
|
||||
define(o16,`.byte 0x66')dnl
|
||||
|
||||
define(addwia,`.byte 0x5; .word $1')dnl
|
||||
define(lgdtwm,`.byte 0xf; .byte 0x1; .byte 0x16; .word $1')dnl
|
||||
define(lidtwm,`.byte 0xf; .byte 0x1; .byte 0x1e; .word $1')dnl
|
||||
define(cmpwmr,`.byte 0x3b; .byte ($2 << 0x3) | 0x6; .word $1')dnl
|
||||
define(cmpwir,`.byte 0x81; .byte 0xf8 | $2; .word $1')dnl
|
||||
define(movbr1,`.byte 0x88; .byte 0x40 | ($1 << 0x3) | $3; .byte $2')dnl
|
||||
define(movwr0,`.byte 0x89; .byte ($1 << 0x3) | $2')dnl
|
||||
define(leaw1r,`.byte 0x8d; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
|
||||
define(movwir,`.byte 0xb8 | $2; .word $1')dnl
|
||||
define(movbi1,`.byte 0xc6; .byte 0x40 | $3; .byte $2; .byte $1')dnl
|
||||
define(callwi,`.byte 0xe8; .word $1 - . - 0x2')dnl
|
||||
define(jmpfwi,`.byte 0xea; .word $2; .word $1')dnl
|
||||
define(tstbim,`.byte 0xf6; .byte 0x6; .word $2; .byte $1')dnl
|
1071
sys/boot/pc98/btx/btx/btx.s
Normal file
1071
sys/boot/pc98/btx/btx/btx.s
Normal file
File diff suppressed because it is too large
Load Diff
26
sys/boot/pc98/btx/btxldr/Makefile
Normal file
26
sys/boot/pc98/btx/btxldr/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
# $Id: Makefile,v 1.6 1998/10/30 00:11:35 msmith Exp $
|
||||
|
||||
ORG=0x100000
|
||||
#AFLAGS+= -x assembler-with-cpp
|
||||
|
||||
#AFLAGS+= --defsym PC98=1 --defsym BTXLDR_VERBOSE=1
|
||||
AFLAGS+= --defsym PC98=1
|
||||
|
||||
all: btxldr
|
||||
|
||||
btxldr: btxldr.o
|
||||
.if ${OBJFORMAT} == aout
|
||||
${LD} -nostdlib -N -s -T ${ORG} -o btxldr.out btxldr.o
|
||||
dd if=btxldr.out of=${.TARGET} ibs=32 skip=1
|
||||
.else
|
||||
${LD} -N -e start -Ttext ${ORG} -o btxldr.out btxldr.o
|
||||
objcopy -S -O binary btxldr.out ${.TARGET}
|
||||
.endif
|
||||
|
||||
btxldr.o: btxldr.s
|
||||
# ${CC} ${AFLAGS} -c -o ${.TARGET} ${.CURDIR}/btxldr.s
|
||||
${AS} ${AFLAGS} -o ${.TARGET} ${.CURDIR}/btxldr.s
|
||||
|
||||
CLEANFILES+= btxldr btxldr.out btxldr.o
|
||||
|
||||
.include <bsd.prog.mk>
|
459
sys/boot/pc98/btx/btxldr/btxldr.S
Normal file
459
sys/boot/pc98/btx/btxldr/btxldr.S
Normal file
@ -0,0 +1,459 @@
|
||||
#
|
||||
# Copyright (c) 1998 Robert Nordier
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms are freely
|
||||
# permitted provided that the above copyright notice and this
|
||||
# paragraph and the following disclaimer are duplicated in all
|
||||
# such forms.
|
||||
#
|
||||
# This software is provided "AS IS" and without any express or
|
||||
# implied warranties, including, without limitation, the implied
|
||||
# warranties of merchantability and fitness for a particular
|
||||
# purpose.
|
||||
#
|
||||
|
||||
# $Id: btxldr.s,v 1.5 1999/01/22 13:07:17 rnordier Exp $
|
||||
|
||||
#
|
||||
# Prototype BTX loader program, written in a couple of hours. The
|
||||
# real thing should probably be more flexible, and in C.
|
||||
#
|
||||
|
||||
#
|
||||
# Memory locations.
|
||||
#
|
||||
.set MEM_STUB,0x600 # Real mode stub
|
||||
.set MEM_ESP,0x1000 # New stack pointer
|
||||
.set MEM_TBL,0x5000 # BTX page tables
|
||||
.set MEM_ENTRY,0x9010 # BTX entry point
|
||||
.set MEM_DATA,0x101000 # Data segment
|
||||
#
|
||||
# Segment selectors.
|
||||
#
|
||||
.set SEL_SCODE,0x8 # 4GB code
|
||||
.set SEL_SDATA,0x10 # 4GB data
|
||||
.set SEL_RCODE,0x18 # 64K code
|
||||
.set SEL_RDATA,0x20 # 64K data
|
||||
#
|
||||
# Paging constants.
|
||||
#
|
||||
.set PAG_SIZ,0x1000 # Page size
|
||||
.set PAG_ENT,0x4 # Page entry size
|
||||
#
|
||||
# Screen constants.
|
||||
#
|
||||
.ifdef PC98
|
||||
.set SCR_MAT,0xe1 # Mode/attribute
|
||||
.else
|
||||
.set SCR_MAT,0x7 # Mode/attribute
|
||||
.endif
|
||||
.set SCR_COL,0x50 # Columns per row
|
||||
.set SCR_ROW,0x19 # Rows per screen
|
||||
#
|
||||
# BIOS Data Area locations.
|
||||
#
|
||||
.ifdef PC98
|
||||
.set BDA_MEM,0xa1501 # Free memory
|
||||
.set BDA_POS,0xa153e # Cursor position
|
||||
.else
|
||||
.set BDA_MEM,0x413 # Free memory
|
||||
.set BDA_SCR,0x449 # Video mode
|
||||
.set BDA_POS,0x450 # Cursor position
|
||||
.endif
|
||||
#
|
||||
# Required by aout gas inadequacy.
|
||||
#
|
||||
.set SIZ_STUB,0x1a # Size of stub
|
||||
#
|
||||
# We expect to be loaded by boot2 at 0x100000.
|
||||
#
|
||||
.globl start
|
||||
#
|
||||
# BTX program loader for ELF clients.
|
||||
#
|
||||
start: cld # String ops inc
|
||||
.ifdef PC98
|
||||
cli
|
||||
gdcwait.1: inb $0x60,%al
|
||||
testb $0x04,%al
|
||||
jz gdcwait.1
|
||||
movb $0xe0,%al
|
||||
outb %al,$0x62
|
||||
nop
|
||||
gdcwait.2: inb $0x60,%al
|
||||
testb $0x01,%al
|
||||
jz gdcwait.2
|
||||
inb $0x62,%al
|
||||
movb %al,%dl
|
||||
inb $0x62,%al
|
||||
movb %al,%dh
|
||||
inb $0x62,%al
|
||||
inb $0x62,%al
|
||||
inb $0x62,%al
|
||||
shlw $1,%dx
|
||||
movl $BDA_POS,%ebx
|
||||
movw %dx,(%ebx)
|
||||
.endif
|
||||
movl $m_logo,%esi # Identify
|
||||
call putstr # ourselves
|
||||
movzwl BDA_MEM,%eax # Get base memory
|
||||
.ifdef PC98
|
||||
andl $0x7,%eax
|
||||
incl %eax
|
||||
shll $0x11,%eax # in bytes
|
||||
.else
|
||||
shll $0xa,%eax # in bytes
|
||||
.endif
|
||||
movl %eax,%ebp # Base of user stack
|
||||
movl $m_mem,%esi # Display
|
||||
call dhexout # amount of
|
||||
call dputstr # base memory
|
||||
lgdt gdtdesc # Load new GDT
|
||||
#
|
||||
# Relocate caller's arguments.
|
||||
#
|
||||
movl $m_esp,%esi # Display
|
||||
movl %esp,%eax # caller's
|
||||
call dhexout # stack
|
||||
call dputstr # pointer
|
||||
movl $m_args,%esi # Format string
|
||||
leal 0x4(%esp,1),%ebx # First argument
|
||||
movl $0x6,%ecx # Count
|
||||
start.1: movl (%ebx),%eax # Get argument and
|
||||
addl $0x4,%ebx # bump pointer
|
||||
call dhexout # Display it
|
||||
loop start.1 # Till done
|
||||
call dputstr # End message
|
||||
movl $0x48,%ecx # Allocate space
|
||||
subl %ecx,%ebp # for bootinfo
|
||||
movl 0x18(%esp,1),%esi # Source
|
||||
movl %ebp,%edi # Destination
|
||||
rep # Copy
|
||||
movsb # it
|
||||
movl %ebp,0x18(%esp,1) # Update pointer
|
||||
movl $m_rel_bi,%esi # Display
|
||||
movl %ebp,%eax # bootinfo
|
||||
call dhexout # relocation
|
||||
call dputstr # message
|
||||
movl $0x18,%ecx # Allocate space
|
||||
subl %ecx,%ebp # for arguments
|
||||
leal 0x4(%esp,1),%esi # Source
|
||||
movl %ebp,%edi # Destination
|
||||
rep # Copy
|
||||
movsb # them
|
||||
movl $m_rel_args,%esi # Display
|
||||
movl %ebp,%eax # argument
|
||||
call dhexout # relocation
|
||||
call dputstr # message
|
||||
#
|
||||
# Set up BTX kernel.
|
||||
#
|
||||
movl $MEM_ESP,%esp # Set up new stack
|
||||
movl $MEM_DATA,%ebx # Data segment
|
||||
movl $m_vers,%esi # Display BTX
|
||||
call putstr # version message
|
||||
movb 0x5(%ebx),%al # Get major version
|
||||
addb $'0',%al # Display
|
||||
call putchr # it
|
||||
movb $'.',%al # And a
|
||||
call putchr # dot
|
||||
movb 0x6(%ebx),%al # Get minor
|
||||
xorb %ah,%ah # version
|
||||
movb $0xa,%dl # Divide
|
||||
divb %dl,%al # by 10
|
||||
addb $'0',%al # Display
|
||||
call putchr # tens
|
||||
movb %ah,%al # Get units
|
||||
addb $'0',%al # Display
|
||||
call putchr # units
|
||||
call putstr # End message
|
||||
movl %ebx,%esi # BTX image
|
||||
movzwl 0x8(%ebx),%edi # Compute
|
||||
orl $PAG_SIZ/PAG_ENT-1,%edi # the
|
||||
incl %edi # BTX
|
||||
shll $0x2,%edi # load
|
||||
addl $MEM_TBL,%edi # address
|
||||
pushl %edi # Save
|
||||
movzwl 0xa(%ebx),%ecx # Image size
|
||||
pushl %ecx # Save
|
||||
rep # Relocate
|
||||
movsb # BTX
|
||||
movl %esi,%ebx # Keep place
|
||||
movl $m_rel_btx,%esi # Restore
|
||||
popl %eax # parameters
|
||||
call dhexout # and
|
||||
popl %ebp # display
|
||||
movl %ebp,%eax # the
|
||||
call dhexout # relocation
|
||||
call dputstr # message
|
||||
addl $PAG_SIZ,%ebp # Display
|
||||
movl $m_base,%esi # the
|
||||
movl %ebp,%eax # user
|
||||
call dhexout # base
|
||||
call dputstr # address
|
||||
#
|
||||
# Set up ELF-format client program.
|
||||
#
|
||||
cmpl $0x464c457f,(%ebx) # ELF magic number?
|
||||
je start.3 # Yes
|
||||
movl $e_fmt,%esi # Display error
|
||||
call putstr # message
|
||||
start.2: jmp start.2 # Hang
|
||||
start.3: movl $m_elf,%esi # Display ELF
|
||||
call dputstr # message
|
||||
movl $m_segs,%esi # Format string
|
||||
movl $0x2,%edi # Segment count
|
||||
movl 0x1c(%ebx),%edx # Get e_phoff
|
||||
addl %ebx,%edx # To pointer
|
||||
movzwl 0x2c(%ebx),%ecx # Get e_phnum
|
||||
start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
|
||||
jne start.6 # No
|
||||
movl 0x4(%edx),%eax # Display
|
||||
call dhexout # p_offset
|
||||
movl 0x8(%edx),%eax # Display
|
||||
call dhexout # p_vaddr
|
||||
movl 0x10(%edx),%eax # Display
|
||||
call dhexout # p_filesz
|
||||
movl 0x14(%edx),%eax # Display
|
||||
call dhexout # p_memsz
|
||||
call dputstr # End message
|
||||
pushl %esi # Save
|
||||
pushl %edi # working
|
||||
pushl %ecx # registers
|
||||
movl 0x4(%edx),%esi # Get p_offset
|
||||
addl %ebx,%esi # as pointer
|
||||
movl 0x8(%edx),%edi # Get p_vaddr
|
||||
addl %ebp,%edi # as pointer
|
||||
movl 0x10(%edx),%ecx # Get p_filesz
|
||||
rep # Set up
|
||||
movsb # segment
|
||||
movl 0x14(%edx),%ecx # Any bytes
|
||||
subl 0x10(%edx),%ecx # to zero?
|
||||
jz start.5 # No
|
||||
xorb %al,%al # Then
|
||||
rep # zero
|
||||
stosb # them
|
||||
start.5: popl %ecx # Restore
|
||||
popl %edi # working
|
||||
popl %esi # registers
|
||||
decl %edi # Segments to do
|
||||
je start.7 # If none
|
||||
start.6: addl $0x20,%edx # To next entry
|
||||
loop start.4 # Till done
|
||||
start.7: movl $m_done,%esi # Display done
|
||||
call dputstr # message
|
||||
movl $start.8,%esi # Real mode stub
|
||||
movl $MEM_STUB,%edi # Destination
|
||||
movl $SIZ_STUB,%ecx # Size
|
||||
rep # Relocate
|
||||
movsb # it
|
||||
ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
|
||||
start.8: xorl %eax,%eax # Data
|
||||
movb $SEL_RDATA,%al # selector
|
||||
movl %eax,%ss # Reload SS
|
||||
movl %eax,%ds # Reset
|
||||
movl %eax,%es # other
|
||||
movl %eax,%fs # segment
|
||||
movl %eax,%gs # limits
|
||||
movl %cr0,%eax # Switch to
|
||||
decl %eax # real
|
||||
movl %eax,%cr0 # mode
|
||||
.byte 0xea # Jump to
|
||||
.word MEM_ENTRY # BTX entry
|
||||
.word 0x0 # point
|
||||
start.9:
|
||||
#
|
||||
# Output message [ESI] followed by EAX in hex.
|
||||
#
|
||||
dhexout:
|
||||
.ifndef BTXLDR_VERBOSE
|
||||
ret
|
||||
.endif
|
||||
hexout: pushl %eax # Save
|
||||
call putstr # Display message
|
||||
popl %eax # Restore
|
||||
pushl %esi # Save
|
||||
pushl %edi # caller's
|
||||
movl $buf,%edi # Buffer
|
||||
pushl %edi # Save
|
||||
call hex32 # To hex
|
||||
xorb %al,%al # Terminate
|
||||
stosb # string
|
||||
popl %esi # Restore
|
||||
hexout.1: lodsb # Get a char
|
||||
cmpb $'0',%al # Leading zero?
|
||||
je hexout.1 # Yes
|
||||
testb %al,%al # End of string?
|
||||
jne hexout.2 # No
|
||||
decl %esi # Undo
|
||||
hexout.2: decl %esi # Adjust for inc
|
||||
call putstr # Display hex
|
||||
popl %edi # Restore
|
||||
popl %esi # caller's
|
||||
ret # To caller
|
||||
#
|
||||
# Output zero-terminated string [ESI] to the console.
|
||||
#
|
||||
dputstr:
|
||||
.ifndef BTXLDR_VERBOSE
|
||||
ret
|
||||
.else
|
||||
jmp putstr
|
||||
.endif
|
||||
putstr.0: call putchr # Output char
|
||||
putstr: lodsb # Load char
|
||||
testb %al,%al # End of string?
|
||||
jne putstr.0 # No
|
||||
ret # To caller
|
||||
#
|
||||
# Output character AL to the console.
|
||||
#
|
||||
dputchr:
|
||||
.ifndef BTXLDR_VERBOSE
|
||||
ret
|
||||
.endif
|
||||
putchr: pusha # Save
|
||||
xorl %ecx,%ecx # Zero for loops
|
||||
movb $SCR_MAT,%ah # Mode/attribute
|
||||
movl $BDA_POS,%ebx # BDA pointer
|
||||
movw (%ebx),%dx # Cursor position
|
||||
.ifdef PC98
|
||||
movl $0xa0000,%edi # Regen buffer (color)
|
||||
.else
|
||||
movl $0xb8000,%edi # Regen buffer (color)
|
||||
cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
|
||||
jne putchr.1 # No
|
||||
xorw %di,%di # Regen buffer (mono)
|
||||
.endif
|
||||
putchr.1: cmpb $0xa,%al # New line?
|
||||
je putchr.2 # Yes
|
||||
.ifdef PC98
|
||||
movw %dx,%cx
|
||||
movb %al,(%edi,%ecx,1) # Write char
|
||||
addl $0x2000,%ecx
|
||||
movb %ah,(%edi,%ecx,1) # Write attr
|
||||
addw $0x2,%dx
|
||||
jmp putchr.3
|
||||
putchr.2: movw %dx,%ax
|
||||
movb $SCR_COL*2,%dl
|
||||
div %dl
|
||||
incb %al
|
||||
mul %dl
|
||||
movw %ax,%dx
|
||||
putchr.3: cmpw $SCR_COL*SCR_ROW*2,%dx
|
||||
.else
|
||||
xchgl %eax,%ecx # Save char
|
||||
movb $SCR_COL,%al # Columns per row
|
||||
mulb %dh # * row position
|
||||
addb %dl,%al # + column
|
||||
adcb $0x0,%ah # position
|
||||
shll %eax # * 2
|
||||
xchgl %eax,%ecx # Swap char, offset
|
||||
movw %ax,(%edi,%ecx,1) # Write attr:char
|
||||
incl %edx # Bump cursor
|
||||
cmpb $SCR_COL,%dl # Beyond row?
|
||||
jb putchr.3 # No
|
||||
putchr.2: xorb %dl,%dl # Zero column
|
||||
incb %dh # Bump row
|
||||
putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
|
||||
.endif
|
||||
jb putchr.4 # No
|
||||
leal 2*SCR_COL(%edi),%esi # New top line
|
||||
movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
|
||||
rep # Scroll
|
||||
movsl # screen
|
||||
movb $' ',%al # Space
|
||||
.ifdef PC98
|
||||
xorb %ah,%ah
|
||||
.endif
|
||||
movb $SCR_COL,%cl # Columns to clear
|
||||
rep # Clear
|
||||
stosw # line
|
||||
.ifdef PC98
|
||||
movw $(SCR_ROW-1)*SCR_COL*2,%dx
|
||||
putchr.4: movw %dx,(%ebx) # Update position
|
||||
shrw $1,%dx
|
||||
gdcwait.3: inb $0x60,%al
|
||||
testb $0x04,%al
|
||||
jz gdcwait.3
|
||||
movb $0x49,%al
|
||||
outb %al,$0x62
|
||||
movb %dl,%al
|
||||
outb %al,$0x60
|
||||
movb %dh,%al
|
||||
outb %al,$0x60
|
||||
.else
|
||||
movb $SCR_ROW-1,%dh # Bottom line
|
||||
putchr.4: movw %dx,(%ebx) # Update position
|
||||
.endif
|
||||
popa # Restore
|
||||
ret # To caller
|
||||
#
|
||||
# Convert EAX, AX, or AL to hex, saving the result to [EDI].
|
||||
#
|
||||
hex32: pushl %eax # Save
|
||||
shrl $0x10,%eax # Do upper
|
||||
call hex16 # 16
|
||||
popl %eax # Restore
|
||||
hex16: call hex16.1 # Do upper 8
|
||||
hex16.1: xchgb %ah,%al # Save/restore
|
||||
hex8: pushl %eax # Save
|
||||
shrb $0x4,%al # Do upper
|
||||
call hex8.1 # 4
|
||||
popl %eax # Restore
|
||||
hex8.1: andb $0xf,%al # Get lower 4
|
||||
cmpb $0xa,%al # Convert
|
||||
sbbb $0x69,%al # to hex
|
||||
das # digit
|
||||
orb $0x20,%al # To lower case
|
||||
stosb # Save char
|
||||
ret # (Recursive)
|
||||
|
||||
.data
|
||||
.p2align 4
|
||||
#
|
||||
# Global descriptor table.
|
||||
#
|
||||
gdt: .word 0x0,0x0,0x0,0x0 # Null entry
|
||||
.word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
|
||||
.word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
|
||||
.word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
|
||||
.word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
|
||||
gdt.1:
|
||||
gdtdesc: .word gdt.1-gdt-1 # Limit
|
||||
.long gdt # Base
|
||||
#
|
||||
# Messages.
|
||||
#
|
||||
m_logo: .asciz "\nBTX loader 1.00 "
|
||||
m_vers: .asciz "BTX version is \0\n"
|
||||
e_fmt: .asciz "Error: Client format not supported\n"
|
||||
#.ifdef BTXLDR_VERBOSE
|
||||
m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
|
||||
m_esp: .asciz "Arguments passed (esp=\0):\n"
|
||||
m_args: .asciz"<howto="
|
||||
.asciz" bootdev="
|
||||
.asciz" junk="
|
||||
.asciz" "
|
||||
.asciz" "
|
||||
.asciz" bootinfo=\0>\n"
|
||||
m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
|
||||
m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
|
||||
m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
|
||||
m_base: .asciz "Client base address is \0\n"
|
||||
m_elf: .asciz "Client format is ELF\n"
|
||||
m_segs: .asciz "text segment: offset="
|
||||
.asciz " vaddr="
|
||||
.asciz " filesz="
|
||||
.asciz " memsz=\0\n"
|
||||
.asciz "data segment: offset="
|
||||
.asciz " vaddr="
|
||||
.asciz " filesz="
|
||||
.asciz " memsz=\0\n"
|
||||
m_done: .asciz "Loading complete\n"
|
||||
#.endif
|
||||
#
|
||||
# Uninitialized data area.
|
||||
#
|
||||
buf: # Scratch buffer
|
459
sys/boot/pc98/btx/btxldr/btxldr.s
Normal file
459
sys/boot/pc98/btx/btxldr/btxldr.s
Normal file
@ -0,0 +1,459 @@
|
||||
#
|
||||
# Copyright (c) 1998 Robert Nordier
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms are freely
|
||||
# permitted provided that the above copyright notice and this
|
||||
# paragraph and the following disclaimer are duplicated in all
|
||||
# such forms.
|
||||
#
|
||||
# This software is provided "AS IS" and without any express or
|
||||
# implied warranties, including, without limitation, the implied
|
||||
# warranties of merchantability and fitness for a particular
|
||||
# purpose.
|
||||
#
|
||||
|
||||
# $Id: btxldr.s,v 1.5 1999/01/22 13:07:17 rnordier Exp $
|
||||
|
||||
#
|
||||
# Prototype BTX loader program, written in a couple of hours. The
|
||||
# real thing should probably be more flexible, and in C.
|
||||
#
|
||||
|
||||
#
|
||||
# Memory locations.
|
||||
#
|
||||
.set MEM_STUB,0x600 # Real mode stub
|
||||
.set MEM_ESP,0x1000 # New stack pointer
|
||||
.set MEM_TBL,0x5000 # BTX page tables
|
||||
.set MEM_ENTRY,0x9010 # BTX entry point
|
||||
.set MEM_DATA,0x101000 # Data segment
|
||||
#
|
||||
# Segment selectors.
|
||||
#
|
||||
.set SEL_SCODE,0x8 # 4GB code
|
||||
.set SEL_SDATA,0x10 # 4GB data
|
||||
.set SEL_RCODE,0x18 # 64K code
|
||||
.set SEL_RDATA,0x20 # 64K data
|
||||
#
|
||||
# Paging constants.
|
||||
#
|
||||
.set PAG_SIZ,0x1000 # Page size
|
||||
.set PAG_ENT,0x4 # Page entry size
|
||||
#
|
||||
# Screen constants.
|
||||
#
|
||||
.ifdef PC98
|
||||
.set SCR_MAT,0xe1 # Mode/attribute
|
||||
.else
|
||||
.set SCR_MAT,0x7 # Mode/attribute
|
||||
.endif
|
||||
.set SCR_COL,0x50 # Columns per row
|
||||
.set SCR_ROW,0x19 # Rows per screen
|
||||
#
|
||||
# BIOS Data Area locations.
|
||||
#
|
||||
.ifdef PC98
|
||||
.set BDA_MEM,0xa1501 # Free memory
|
||||
.set BDA_POS,0xa153e # Cursor position
|
||||
.else
|
||||
.set BDA_MEM,0x413 # Free memory
|
||||
.set BDA_SCR,0x449 # Video mode
|
||||
.set BDA_POS,0x450 # Cursor position
|
||||
.endif
|
||||
#
|
||||
# Required by aout gas inadequacy.
|
||||
#
|
||||
.set SIZ_STUB,0x1a # Size of stub
|
||||
#
|
||||
# We expect to be loaded by boot2 at 0x100000.
|
||||
#
|
||||
.globl start
|
||||
#
|
||||
# BTX program loader for ELF clients.
|
||||
#
|
||||
start: cld # String ops inc
|
||||
.ifdef PC98
|
||||
cli
|
||||
gdcwait.1: inb $0x60,%al
|
||||
testb $0x04,%al
|
||||
jz gdcwait.1
|
||||
movb $0xe0,%al
|
||||
outb %al,$0x62
|
||||
nop
|
||||
gdcwait.2: inb $0x60,%al
|
||||
testb $0x01,%al
|
||||
jz gdcwait.2
|
||||
inb $0x62,%al
|
||||
movb %al,%dl
|
||||
inb $0x62,%al
|
||||
movb %al,%dh
|
||||
inb $0x62,%al
|
||||
inb $0x62,%al
|
||||
inb $0x62,%al
|
||||
shlw $1,%dx
|
||||
movl $BDA_POS,%ebx
|
||||
movw %dx,(%ebx)
|
||||
.endif
|
||||
movl $m_logo,%esi # Identify
|
||||
call putstr # ourselves
|
||||
movzwl BDA_MEM,%eax # Get base memory
|
||||
.ifdef PC98
|
||||
andl $0x7,%eax
|
||||
incl %eax
|
||||
shll $0x11,%eax # in bytes
|
||||
.else
|
||||
shll $0xa,%eax # in bytes
|
||||
.endif
|
||||
movl %eax,%ebp # Base of user stack
|
||||
movl $m_mem,%esi # Display
|
||||
call dhexout # amount of
|
||||
call dputstr # base memory
|
||||
lgdt gdtdesc # Load new GDT
|
||||
#
|
||||
# Relocate caller's arguments.
|
||||
#
|
||||
movl $m_esp,%esi # Display
|
||||
movl %esp,%eax # caller's
|
||||
call dhexout # stack
|
||||
call dputstr # pointer
|
||||
movl $m_args,%esi # Format string
|
||||
leal 0x4(%esp,1),%ebx # First argument
|
||||
movl $0x6,%ecx # Count
|
||||
start.1: movl (%ebx),%eax # Get argument and
|
||||
addl $0x4,%ebx # bump pointer
|
||||
call dhexout # Display it
|
||||
loop start.1 # Till done
|
||||
call dputstr # End message
|
||||
movl $0x48,%ecx # Allocate space
|
||||
subl %ecx,%ebp # for bootinfo
|
||||
movl 0x18(%esp,1),%esi # Source
|
||||
movl %ebp,%edi # Destination
|
||||
rep # Copy
|
||||
movsb # it
|
||||
movl %ebp,0x18(%esp,1) # Update pointer
|
||||
movl $m_rel_bi,%esi # Display
|
||||
movl %ebp,%eax # bootinfo
|
||||
call dhexout # relocation
|
||||
call dputstr # message
|
||||
movl $0x18,%ecx # Allocate space
|
||||
subl %ecx,%ebp # for arguments
|
||||
leal 0x4(%esp,1),%esi # Source
|
||||
movl %ebp,%edi # Destination
|
||||
rep # Copy
|
||||
movsb # them
|
||||
movl $m_rel_args,%esi # Display
|
||||
movl %ebp,%eax # argument
|
||||
call dhexout # relocation
|
||||
call dputstr # message
|
||||
#
|
||||
# Set up BTX kernel.
|
||||
#
|
||||
movl $MEM_ESP,%esp # Set up new stack
|
||||
movl $MEM_DATA,%ebx # Data segment
|
||||
movl $m_vers,%esi # Display BTX
|
||||
call putstr # version message
|
||||
movb 0x5(%ebx),%al # Get major version
|
||||
addb $'0',%al # Display
|
||||
call putchr # it
|
||||
movb $'.',%al # And a
|
||||
call putchr # dot
|
||||
movb 0x6(%ebx),%al # Get minor
|
||||
xorb %ah,%ah # version
|
||||
movb $0xa,%dl # Divide
|
||||
divb %dl,%al # by 10
|
||||
addb $'0',%al # Display
|
||||
call putchr # tens
|
||||
movb %ah,%al # Get units
|
||||
addb $'0',%al # Display
|
||||
call putchr # units
|
||||
call putstr # End message
|
||||
movl %ebx,%esi # BTX image
|
||||
movzwl 0x8(%ebx),%edi # Compute
|
||||
orl $PAG_SIZ/PAG_ENT-1,%edi # the
|
||||
incl %edi # BTX
|
||||
shll $0x2,%edi # load
|
||||
addl $MEM_TBL,%edi # address
|
||||
pushl %edi # Save
|
||||
movzwl 0xa(%ebx),%ecx # Image size
|
||||
pushl %ecx # Save
|
||||
rep # Relocate
|
||||
movsb # BTX
|
||||
movl %esi,%ebx # Keep place
|
||||
movl $m_rel_btx,%esi # Restore
|
||||
popl %eax # parameters
|
||||
call dhexout # and
|
||||
popl %ebp # display
|
||||
movl %ebp,%eax # the
|
||||
call dhexout # relocation
|
||||
call dputstr # message
|
||||
addl $PAG_SIZ,%ebp # Display
|
||||
movl $m_base,%esi # the
|
||||
movl %ebp,%eax # user
|
||||
call dhexout # base
|
||||
call dputstr # address
|
||||
#
|
||||
# Set up ELF-format client program.
|
||||
#
|
||||
cmpl $0x464c457f,(%ebx) # ELF magic number?
|
||||
je start.3 # Yes
|
||||
movl $e_fmt,%esi # Display error
|
||||
call putstr # message
|
||||
start.2: jmp start.2 # Hang
|
||||
start.3: movl $m_elf,%esi # Display ELF
|
||||
call dputstr # message
|
||||
movl $m_segs,%esi # Format string
|
||||
movl $0x2,%edi # Segment count
|
||||
movl 0x1c(%ebx),%edx # Get e_phoff
|
||||
addl %ebx,%edx # To pointer
|
||||
movzwl 0x2c(%ebx),%ecx # Get e_phnum
|
||||
start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
|
||||
jne start.6 # No
|
||||
movl 0x4(%edx),%eax # Display
|
||||
call dhexout # p_offset
|
||||
movl 0x8(%edx),%eax # Display
|
||||
call dhexout # p_vaddr
|
||||
movl 0x10(%edx),%eax # Display
|
||||
call dhexout # p_filesz
|
||||
movl 0x14(%edx),%eax # Display
|
||||
call dhexout # p_memsz
|
||||
call dputstr # End message
|
||||
pushl %esi # Save
|
||||
pushl %edi # working
|
||||
pushl %ecx # registers
|
||||
movl 0x4(%edx),%esi # Get p_offset
|
||||
addl %ebx,%esi # as pointer
|
||||
movl 0x8(%edx),%edi # Get p_vaddr
|
||||
addl %ebp,%edi # as pointer
|
||||
movl 0x10(%edx),%ecx # Get p_filesz
|
||||
rep # Set up
|
||||
movsb # segment
|
||||
movl 0x14(%edx),%ecx # Any bytes
|
||||
subl 0x10(%edx),%ecx # to zero?
|
||||
jz start.5 # No
|
||||
xorb %al,%al # Then
|
||||
rep # zero
|
||||
stosb # them
|
||||
start.5: popl %ecx # Restore
|
||||
popl %edi # working
|
||||
popl %esi # registers
|
||||
decl %edi # Segments to do
|
||||
je start.7 # If none
|
||||
start.6: addl $0x20,%edx # To next entry
|
||||
loop start.4 # Till done
|
||||
start.7: movl $m_done,%esi # Display done
|
||||
call dputstr # message
|
||||
movl $start.8,%esi # Real mode stub
|
||||
movl $MEM_STUB,%edi # Destination
|
||||
movl $SIZ_STUB,%ecx # Size
|
||||
rep # Relocate
|
||||
movsb # it
|
||||
ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
|
||||
start.8: xorl %eax,%eax # Data
|
||||
movb $SEL_RDATA,%al # selector
|
||||
movl %eax,%ss # Reload SS
|
||||
movl %eax,%ds # Reset
|
||||
movl %eax,%es # other
|
||||
movl %eax,%fs # segment
|
||||
movl %eax,%gs # limits
|
||||
movl %cr0,%eax # Switch to
|
||||
decl %eax # real
|
||||
movl %eax,%cr0 # mode
|
||||
.byte 0xea # Jump to
|
||||
.word MEM_ENTRY # BTX entry
|
||||
.word 0x0 # point
|
||||
start.9:
|
||||
#
|
||||
# Output message [ESI] followed by EAX in hex.
|
||||
#
|
||||
dhexout:
|
||||
.ifndef BTXLDR_VERBOSE
|
||||
ret
|
||||
.endif
|
||||
hexout: pushl %eax # Save
|
||||
call putstr # Display message
|
||||
popl %eax # Restore
|
||||
pushl %esi # Save
|
||||
pushl %edi # caller's
|
||||
movl $buf,%edi # Buffer
|
||||
pushl %edi # Save
|
||||
call hex32 # To hex
|
||||
xorb %al,%al # Terminate
|
||||
stosb # string
|
||||
popl %esi # Restore
|
||||
hexout.1: lodsb # Get a char
|
||||
cmpb $'0',%al # Leading zero?
|
||||
je hexout.1 # Yes
|
||||
testb %al,%al # End of string?
|
||||
jne hexout.2 # No
|
||||
decl %esi # Undo
|
||||
hexout.2: decl %esi # Adjust for inc
|
||||
call putstr # Display hex
|
||||
popl %edi # Restore
|
||||
popl %esi # caller's
|
||||
ret # To caller
|
||||
#
|
||||
# Output zero-terminated string [ESI] to the console.
|
||||
#
|
||||
dputstr:
|
||||
.ifndef BTXLDR_VERBOSE
|
||||
ret
|
||||
.else
|
||||
jmp putstr
|
||||
.endif
|
||||
putstr.0: call putchr # Output char
|
||||
putstr: lodsb # Load char
|
||||
testb %al,%al # End of string?
|
||||
jne putstr.0 # No
|
||||
ret # To caller
|
||||
#
|
||||
# Output character AL to the console.
|
||||
#
|
||||
dputchr:
|
||||
.ifndef BTXLDR_VERBOSE
|
||||
ret
|
||||
.endif
|
||||
putchr: pusha # Save
|
||||
xorl %ecx,%ecx # Zero for loops
|
||||
movb $SCR_MAT,%ah # Mode/attribute
|
||||
movl $BDA_POS,%ebx # BDA pointer
|
||||
movw (%ebx),%dx # Cursor position
|
||||
.ifdef PC98
|
||||
movl $0xa0000,%edi # Regen buffer (color)
|
||||
.else
|
||||
movl $0xb8000,%edi # Regen buffer (color)
|
||||
cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
|
||||
jne putchr.1 # No
|
||||
xorw %di,%di # Regen buffer (mono)
|
||||
.endif
|
||||
putchr.1: cmpb $0xa,%al # New line?
|
||||
je putchr.2 # Yes
|
||||
.ifdef PC98
|
||||
movw %dx,%cx
|
||||
movb %al,(%edi,%ecx,1) # Write char
|
||||
addl $0x2000,%ecx
|
||||
movb %ah,(%edi,%ecx,1) # Write attr
|
||||
addw $0x2,%dx
|
||||
jmp putchr.3
|
||||
putchr.2: movw %dx,%ax
|
||||
movb $SCR_COL*2,%dl
|
||||
div %dl
|
||||
incb %al
|
||||
mul %dl
|
||||
movw %ax,%dx
|
||||
putchr.3: cmpw $SCR_COL*SCR_ROW*2,%dx
|
||||
.else
|
||||
xchgl %eax,%ecx # Save char
|
||||
movb $SCR_COL,%al # Columns per row
|
||||
mulb %dh # * row position
|
||||
addb %dl,%al # + column
|
||||
adcb $0x0,%ah # position
|
||||
shll %eax # * 2
|
||||
xchgl %eax,%ecx # Swap char, offset
|
||||
movw %ax,(%edi,%ecx,1) # Write attr:char
|
||||
incl %edx # Bump cursor
|
||||
cmpb $SCR_COL,%dl # Beyond row?
|
||||
jb putchr.3 # No
|
||||
putchr.2: xorb %dl,%dl # Zero column
|
||||
incb %dh # Bump row
|
||||
putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
|
||||
.endif
|
||||
jb putchr.4 # No
|
||||
leal 2*SCR_COL(%edi),%esi # New top line
|
||||
movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
|
||||
rep # Scroll
|
||||
movsl # screen
|
||||
movb $' ',%al # Space
|
||||
.ifdef PC98
|
||||
xorb %ah,%ah
|
||||
.endif
|
||||
movb $SCR_COL,%cl # Columns to clear
|
||||
rep # Clear
|
||||
stosw # line
|
||||
.ifdef PC98
|
||||
movw $(SCR_ROW-1)*SCR_COL*2,%dx
|
||||
putchr.4: movw %dx,(%ebx) # Update position
|
||||
shrw $1,%dx
|
||||
gdcwait.3: inb $0x60,%al
|
||||
testb $0x04,%al
|
||||
jz gdcwait.3
|
||||
movb $0x49,%al
|
||||
outb %al,$0x62
|
||||
movb %dl,%al
|
||||
outb %al,$0x60
|
||||
movb %dh,%al
|
||||
outb %al,$0x60
|
||||
.else
|
||||
movb $SCR_ROW-1,%dh # Bottom line
|
||||
putchr.4: movw %dx,(%ebx) # Update position
|
||||
.endif
|
||||
popa # Restore
|
||||
ret # To caller
|
||||
#
|
||||
# Convert EAX, AX, or AL to hex, saving the result to [EDI].
|
||||
#
|
||||
hex32: pushl %eax # Save
|
||||
shrl $0x10,%eax # Do upper
|
||||
call hex16 # 16
|
||||
popl %eax # Restore
|
||||
hex16: call hex16.1 # Do upper 8
|
||||
hex16.1: xchgb %ah,%al # Save/restore
|
||||
hex8: pushl %eax # Save
|
||||
shrb $0x4,%al # Do upper
|
||||
call hex8.1 # 4
|
||||
popl %eax # Restore
|
||||
hex8.1: andb $0xf,%al # Get lower 4
|
||||
cmpb $0xa,%al # Convert
|
||||
sbbb $0x69,%al # to hex
|
||||
das # digit
|
||||
orb $0x20,%al # To lower case
|
||||
stosb # Save char
|
||||
ret # (Recursive)
|
||||
|
||||
.data
|
||||
.p2align 4
|
||||
#
|
||||
# Global descriptor table.
|
||||
#
|
||||
gdt: .word 0x0,0x0,0x0,0x0 # Null entry
|
||||
.word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
|
||||
.word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
|
||||
.word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
|
||||
.word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
|
||||
gdt.1:
|
||||
gdtdesc: .word gdt.1-gdt-1 # Limit
|
||||
.long gdt # Base
|
||||
#
|
||||
# Messages.
|
||||
#
|
||||
m_logo: .asciz "\nBTX loader 1.00 "
|
||||
m_vers: .asciz "BTX version is \0\n"
|
||||
e_fmt: .asciz "Error: Client format not supported\n"
|
||||
#.ifdef BTXLDR_VERBOSE
|
||||
m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
|
||||
m_esp: .asciz "Arguments passed (esp=\0):\n"
|
||||
m_args: .asciz"<howto="
|
||||
.asciz" bootdev="
|
||||
.asciz" junk="
|
||||
.asciz" "
|
||||
.asciz" "
|
||||
.asciz" bootinfo=\0>\n"
|
||||
m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
|
||||
m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
|
||||
m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
|
||||
m_base: .asciz "Client base address is \0\n"
|
||||
m_elf: .asciz "Client format is ELF\n"
|
||||
m_segs: .asciz "text segment: offset="
|
||||
.asciz " vaddr="
|
||||
.asciz " filesz="
|
||||
.asciz " memsz=\0\n"
|
||||
.asciz "data segment: offset="
|
||||
.asciz " vaddr="
|
||||
.asciz " filesz="
|
||||
.asciz " memsz=\0\n"
|
||||
m_done: .asciz "Loading complete\n"
|
||||
#.endif
|
||||
#
|
||||
# Uninitialized data area.
|
||||
#
|
||||
buf: # Scratch buffer
|
20
sys/boot/pc98/btx/lib/Makefile
Normal file
20
sys/boot/pc98/btx/lib/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# $Id: Makefile,v 1.2 1998/10/11 11:27:48 rnordier Exp $
|
||||
|
||||
OBJS= btxcsu.o btxsys.o btxv86.o
|
||||
AFLAGS+= -elf
|
||||
LDFLAGS+= -elf
|
||||
CLEANFILES+= crt0.o
|
||||
INTERNALLIB= true
|
||||
NOMAN= true
|
||||
NOPIC= true
|
||||
NOPROFILE= true
|
||||
|
||||
all: crt0.o
|
||||
|
||||
crt0.o: ${OBJS}
|
||||
${LD} ${LDFLAGS} -i -o ${.TARGET} ${OBJS}
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
||||
.s.o:
|
||||
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
|
43
sys/boot/pc98/btx/lib/btxcsu.s
Normal file
43
sys/boot/pc98/btx/lib/btxcsu.s
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (c) 1998 Robert Nordier
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms are freely
|
||||
# permitted provided that the above copyright notice and this
|
||||
# paragraph and the following disclaimer are duplicated in all
|
||||
# such forms.
|
||||
#
|
||||
# This software is provided "AS IS" and without any express or
|
||||
# implied warranties, including, without limitation, the implied
|
||||
# warranties of merchantability and fitness for a particular
|
||||
# purpose.
|
||||
#
|
||||
|
||||
# $Id: btxcsu.s,v 1.2 1998/10/04 21:15:45 rnordier Exp $
|
||||
|
||||
#
|
||||
# BTX C startup code (ELF).
|
||||
#
|
||||
|
||||
#
|
||||
# Globals.
|
||||
#
|
||||
.global _start
|
||||
#
|
||||
# Constants.
|
||||
#
|
||||
.set ARGADJ,0xfa0 # Argument adjustment
|
||||
#
|
||||
# Client entry point.
|
||||
#
|
||||
_start: movl %eax,__base # Set base address
|
||||
movl %esp,%eax # Set
|
||||
addl $ARGADJ,%eax # argument
|
||||
movl %eax,__args # pointer
|
||||
call main # Invoke client main()
|
||||
call exit # Invoke client exit()
|
||||
#
|
||||
# Data.
|
||||
#
|
||||
.comm __base,4 # Client base address
|
||||
.comm __args,4 # Client arguments
|
40
sys/boot/pc98/btx/lib/btxsys.s
Normal file
40
sys/boot/pc98/btx/lib/btxsys.s
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (c) 1998 Robert Nordier
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms are freely
|
||||
# permitted provided that the above copyright notice and this
|
||||
# paragraph and the following disclaimer are duplicated in all
|
||||
# such forms.
|
||||
#
|
||||
# This software is provided "AS IS" and without any express or
|
||||
# implied warranties, including, without limitation, the implied
|
||||
# warranties of merchantability and fitness for a particular
|
||||
# purpose.
|
||||
#
|
||||
|
||||
# $Id: btxsys.s,v 1.1 1998/09/14 10:37:00 rnordier Exp $
|
||||
|
||||
#
|
||||
# BTX system calls.
|
||||
#
|
||||
|
||||
#
|
||||
# Globals.
|
||||
#
|
||||
.global __exit
|
||||
.global __exec
|
||||
#
|
||||
# Constants.
|
||||
#
|
||||
.set INT_SYS,0x30 # Interrupt number
|
||||
#
|
||||
# System call: exit
|
||||
#
|
||||
__exit: xorl %eax,%eax # BTX system
|
||||
int $INT_SYS # call 0x0
|
||||
#
|
||||
# System call: exec
|
||||
#
|
||||
__exec: movl $0x1,%eax # BTX system
|
||||
int $INT_SYS # call 0x1
|
63
sys/boot/pc98/btx/lib/btxv86.h
Normal file
63
sys/boot/pc98/btx/lib/btxv86.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are freely
|
||||
* permitted provided that the above copyright notice and this
|
||||
* paragraph and the following disclaimer are duplicated in all
|
||||
* such forms.
|
||||
*
|
||||
* This software is provided "AS IS" and without any express or
|
||||
* implied warranties, including, without limitation, the implied
|
||||
* warranties of merchantability and fitness for a particular
|
||||
* purpose.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: btxv86.h,v 1.4 1998/10/02 20:52:26 msmith Exp $
|
||||
*/
|
||||
|
||||
#ifndef _BTXV86_H_
|
||||
#define _BTXV86_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define V86_ADDR 0x10000 /* Segment:offset address */
|
||||
#define V86_CALLF 0x20000 /* Emulate far call */
|
||||
#define V86_FLAGS 0x40000 /* Return flags */
|
||||
|
||||
struct __v86 {
|
||||
uint32_t ctl; /* Control flags */
|
||||
uint32_t addr; /* Interrupt number or address */
|
||||
uint32_t es; /* V86 ES register */
|
||||
uint32_t ds; /* V86 DS register */
|
||||
uint32_t fs; /* V86 FS register */
|
||||
uint32_t gs; /* V86 GS register */
|
||||
uint32_t eax; /* V86 EAX register */
|
||||
uint32_t ecx; /* V86 ECX register */
|
||||
uint32_t edx; /* V86 EDX register */
|
||||
uint32_t ebx; /* V86 EBX register */
|
||||
uint32_t efl; /* V86 eflags register */
|
||||
uint32_t ebp; /* V86 EBP register */
|
||||
uint32_t esi; /* V86 ESI register */
|
||||
uint32_t edi; /* V86 EDI register */
|
||||
};
|
||||
|
||||
extern struct __v86 __v86; /* V86 interface structure */
|
||||
void __v86int(void);
|
||||
|
||||
#define v86 __v86
|
||||
#define v86int __v86int
|
||||
|
||||
extern u_int32_t __base;
|
||||
extern u_int32_t __args;
|
||||
|
||||
#define PTOV(pa) ((caddr_t)(pa) - __base)
|
||||
#define VTOP(va) ((vm_offset_t)(va) + __base)
|
||||
#define VTOPSEG(va) (u_int16_t)(VTOP((caddr_t)va) >> 4)
|
||||
#define VTOPOFF(va) (u_int16_t)(VTOP((caddr_t)va) & 0xf)
|
||||
|
||||
void __exit(int) __attribute__((__noreturn__));
|
||||
void __exec(caddr_t, ...);
|
||||
|
||||
#endif /* !_BTXV86_H_ */
|
85
sys/boot/pc98/btx/lib/btxv86.s
Normal file
85
sys/boot/pc98/btx/lib/btxv86.s
Normal file
@ -0,0 +1,85 @@
|
||||
#
|
||||
# Copyright (c) 1998 Robert Nordier
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms are freely
|
||||
# permitted provided that the above copyright notice and this
|
||||
# paragraph and the following disclaimer are duplicated in all
|
||||
# such forms.
|
||||
#
|
||||
# This software is provided "AS IS" and without any express or
|
||||
# implied warranties, including, without limitation, the implied
|
||||
# warranties of merchantability and fitness for a particular
|
||||
# purpose.
|
||||
#
|
||||
|
||||
# $Id: btxv86.s,v 1.2 1998/10/22 20:22:07 msmith Exp $
|
||||
|
||||
#
|
||||
# BTX V86 interface.
|
||||
#
|
||||
|
||||
#
|
||||
# Globals.
|
||||
#
|
||||
.global __v86int
|
||||
#
|
||||
# Fields in V86 interface structure.
|
||||
#
|
||||
.set V86_CTL,0x0 # Control flags
|
||||
.set V86_ADDR,0x4 # Int number/address
|
||||
.set V86_ES,0x8 # V86 ES
|
||||
.set V86_DS,0xc # V86 DS
|
||||
.set V86_FS,0x10 # V86 FS
|
||||
.set V86_GS,0x14 # V86 GS
|
||||
.set V86_EAX,0x18 # V86 EAX
|
||||
.set V86_ECX,0x1c # V86 ECX
|
||||
.set V86_EDX,0x20 # V86 EDX
|
||||
.set V86_EBX,0x24 # V86 EBX
|
||||
.set V86_EFL,0x28 # V86 eflags
|
||||
.set V86_EBP,0x2c # V86 EBP
|
||||
.set V86_ESI,0x30 # V86 ESI
|
||||
.set V86_EDI,0x34 # V86 EDI
|
||||
#
|
||||
# Other constants.
|
||||
#
|
||||
.set INT_V86,0x31 # Interrupt number
|
||||
.set SIZ_V86,0x38 # Size of V86 structure
|
||||
#
|
||||
# V86 interface function.
|
||||
#
|
||||
__v86int: popl __v86ret # Save return address
|
||||
pushl $__v86 # Push pointer
|
||||
call __v86_swap # Load V86 registers
|
||||
int $INT_V86 # To BTX
|
||||
call __v86_swap # Load user registers
|
||||
addl $0x4,%esp # Discard pointer
|
||||
pushl __v86ret # Restore return address
|
||||
ret # To user
|
||||
#
|
||||
# Swap V86 and user registers.
|
||||
#
|
||||
__v86_swap: xchgl %ebp,0x4(%esp,1) # Swap pointer, EBP
|
||||
xchgl %eax,V86_EAX(%ebp) # Swap EAX
|
||||
xchgl %ecx,V86_ECX(%ebp) # Swap ECX
|
||||
xchgl %edx,V86_EDX(%ebp) # Swap EDX
|
||||
xchgl %ebx,V86_EBX(%ebp) # Swap EBX
|
||||
pushl %eax # Save
|
||||
pushf # Put eflags
|
||||
popl %eax # in EAX
|
||||
xchgl %eax,V86_EFL(%ebp) # Swap
|
||||
pushl %eax # Put EAX
|
||||
popf # in eflags
|
||||
movl 0x8(%esp,1),%eax # Load EBP
|
||||
xchgl %eax,V86_EBP(%ebp) # Swap
|
||||
movl %eax,0x8(%esp,1) # Save EBP
|
||||
popl %eax # Restore
|
||||
xchgl %esi,V86_ESI(%ebp) # Swap ESI
|
||||
xchgl %edi,V86_EDI(%ebp) # Swap EDI
|
||||
xchgl %ebp,0x4(%esp,1) # Swap pointer, EBP
|
||||
ret # To caller
|
||||
#
|
||||
# V86 interface structure.
|
||||
#
|
||||
.comm __v86,SIZ_V86
|
||||
.comm __v86ret,4
|
42
sys/boot/pc98/libpc98/Makefile
Normal file
42
sys/boot/pc98/libpc98/Makefile
Normal file
@ -0,0 +1,42 @@
|
||||
# $Id: Makefile,v 1.13 1999/01/10 14:48:04 rnordier Exp $
|
||||
#
|
||||
LIB= pc98
|
||||
NOPIC=
|
||||
NOPROFILE=
|
||||
INTERNALLIB= true
|
||||
INTERNALSTATICLIB= true
|
||||
|
||||
SRCS= aout_freebsd.c biosdisk.c biosmem.c biospnp.c biospci.c \
|
||||
bootinfo.c comconsole.c devicename.c elf_freebsd.c gatea20.c \
|
||||
i386_copy.c i386_module.c time.c vidconsole.c
|
||||
.PATH: ${.CURDIR}/../../i386/libi386
|
||||
|
||||
CFLAGS+= -DPC98
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \
|
||||
-I${.CURDIR}/../../.. -I. -I${.CURDIR}/../../i386/libi386
|
||||
|
||||
BOOT_COMCONSOLE_PORT?= 0x238
|
||||
CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT}
|
||||
|
||||
BOOT_COMCONSOLE_SPEED?= 9600
|
||||
CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
|
||||
|
||||
# Make the disk code more talkative
|
||||
#CFLAGS+= -DDISK_DEBUG
|
||||
|
||||
# Include simple terminal emulation (cons25-compatible)
|
||||
CFLAGS+= -DTERM_EMU
|
||||
|
||||
# If it's not there, don't consider it a target
|
||||
.if exists(${.CURDIR}/../../../i386/include)
|
||||
beforedepend ${OBJS}: machine
|
||||
|
||||
machine:
|
||||
ln -sf ${.CURDIR}/../../../i386/include machine
|
||||
|
||||
.endif
|
||||
|
||||
CLEANFILES+= machine
|
||||
|
||||
.include <bsd.lib.mk>
|
1017
sys/boot/pc98/libpc98/biosdisk.c
Normal file
1017
sys/boot/pc98/libpc98/biosdisk.c
Normal file
File diff suppressed because it is too large
Load Diff
59
sys/boot/pc98/libpc98/biosmem.c
Normal file
59
sys/boot/pc98/libpc98/biosmem.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* mjs copyright
|
||||
*/
|
||||
|
||||
/*
|
||||
* Obtain memory configuration information from the BIOS
|
||||
*
|
||||
* Note that we don't try too hard here; knowing the size of
|
||||
* base memory and extended memory out to 16 or 64M is enough for
|
||||
* the requirements of the bootstrap.
|
||||
*
|
||||
* We also maintain a pointer to the top of physical memory
|
||||
* once called to allow rangechecking of load/copy requests.
|
||||
*/
|
||||
#include <stand.h>
|
||||
#include "btxv86.h"
|
||||
|
||||
vm_offset_t memtop;
|
||||
|
||||
/*
|
||||
* Return base memory size in kB.
|
||||
*/
|
||||
int
|
||||
getbasemem(void)
|
||||
{
|
||||
#ifdef PC98
|
||||
return ((*(u_char *)PTOV(0xA1501)&0x07)+1)*128;
|
||||
#else
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x12; /* int 0x12 */
|
||||
v86int();
|
||||
|
||||
return(v86.eax & 0xffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Return extended memory size in kB
|
||||
*/
|
||||
int
|
||||
getextmem(void)
|
||||
{
|
||||
int extkb;
|
||||
|
||||
#ifdef PC98
|
||||
extkb = *(u_char *)PTOV(0xA1401)*128 + *(unsigned short *)PTOV(0xA1594)*1024;
|
||||
#else
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x15; /* int 0x15 function 0x88*/
|
||||
v86.eax = 0x8800;
|
||||
v86int();
|
||||
extkb = v86.eax & 0xffff;
|
||||
#endif
|
||||
/* Set memtop to actual top or 16M, whicheve is less */
|
||||
memtop = min((0x100000 + (extkb * 1024)), (16 * 1024 * 1024));
|
||||
|
||||
return(extkb);
|
||||
}
|
||||
|
331
sys/boot/pc98/libpc98/bootinfo.c
Normal file
331
sys/boot/pc98/libpc98/bootinfo.c
Normal file
@ -0,0 +1,331 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
|
||||
* 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.
|
||||
*
|
||||
* $Id: bootinfo.c,v 1.16 1999/01/24 00:12:04 msmith Exp $
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/linker.h>
|
||||
#include <machine/bootinfo.h>
|
||||
#include "bootstrap.h"
|
||||
#include "libi386.h"
|
||||
#include "btxv86.h"
|
||||
|
||||
static struct bootinfo bi;
|
||||
#ifdef PC98
|
||||
extern struct bootinfo *initial_bootinfo;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return a 'boothowto' value corresponding to the kernel arguments in
|
||||
* (kargs) and any relevant environment variables.
|
||||
*/
|
||||
static struct
|
||||
{
|
||||
char *ev;
|
||||
int mask;
|
||||
} howto_names[] = {
|
||||
{"boot_askname", RB_ASKNAME},
|
||||
{"boot_userconfig", RB_CONFIG},
|
||||
{"boot_ddb", RB_KDB},
|
||||
{"boot_gdb", RB_GDB},
|
||||
{"boot_single", RB_SINGLE},
|
||||
{"boot_verbose", RB_VERBOSE},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
int
|
||||
bi_getboothowto(char *kargs)
|
||||
{
|
||||
char *cp;
|
||||
int howto;
|
||||
int active;
|
||||
int i;
|
||||
|
||||
/* Parse kargs */
|
||||
howto = 0;
|
||||
if (kargs != NULL) {
|
||||
cp = kargs;
|
||||
active = 0;
|
||||
while (*cp != 0) {
|
||||
if (!active && (*cp == '-')) {
|
||||
active = 1;
|
||||
} else if (active)
|
||||
switch (*cp) {
|
||||
case 'a':
|
||||
howto |= RB_ASKNAME;
|
||||
break;
|
||||
case 'c':
|
||||
howto |= RB_CONFIG;
|
||||
break;
|
||||
case 'd':
|
||||
howto |= RB_KDB;
|
||||
break;
|
||||
case 'g':
|
||||
howto |= RB_GDB;
|
||||
break;
|
||||
case 'h':
|
||||
howto |= RB_SERIAL;
|
||||
break;
|
||||
case 'r':
|
||||
howto |= RB_DFLTROOT;
|
||||
break;
|
||||
case 's':
|
||||
howto |= RB_SINGLE;
|
||||
break;
|
||||
case 'v':
|
||||
howto |= RB_VERBOSE;
|
||||
break;
|
||||
default:
|
||||
active = 0;
|
||||
break;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
/* get equivalents from the environment */
|
||||
for (i = 0; howto_names[i].ev != NULL; i++)
|
||||
if (getenv(howto_names[i].ev) != NULL)
|
||||
howto |= howto_names[i].mask;
|
||||
if (!strcmp(getenv("console"), "comconsole"))
|
||||
howto |= RB_SERIAL;
|
||||
return(howto);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the environment into the load area starting at (addr).
|
||||
* Each variable is formatted as <name>=<value>, with a single nul
|
||||
* separating each variable, and a double nul terminating the environment.
|
||||
*/
|
||||
vm_offset_t
|
||||
bi_copyenv(vm_offset_t addr)
|
||||
{
|
||||
struct env_var *ep;
|
||||
|
||||
/* traverse the environment */
|
||||
for (ep = environ; ep != NULL; ep = ep->ev_next) {
|
||||
i386_copyin(ep->ev_name, addr, strlen(ep->ev_name));
|
||||
addr += strlen(ep->ev_name);
|
||||
i386_copyin("=", addr, 1);
|
||||
addr++;
|
||||
if (ep->ev_value != NULL) {
|
||||
i386_copyin(ep->ev_value, addr, strlen(ep->ev_value));
|
||||
addr += strlen(ep->ev_value);
|
||||
}
|
||||
i386_copyin("", addr, 1);
|
||||
addr++;
|
||||
}
|
||||
i386_copyin("", addr, 1);
|
||||
addr++;
|
||||
return(addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy module-related data into the load area, where it can be
|
||||
* used as a directory for loaded modules.
|
||||
*
|
||||
* Module data is presented in a self-describing format. Each datum
|
||||
* is preceeded by a 32-bit identifier and a 32-bit size field.
|
||||
*
|
||||
* Currently, the following data are saved:
|
||||
*
|
||||
* MOD_NAME (variable) module name (string)
|
||||
* MOD_TYPE (variable) module type (string)
|
||||
* MOD_ADDR sizeof(vm_offset_t) module load address
|
||||
* MOD_SIZE sizeof(size_t) module size
|
||||
* MOD_METADATA (variable) type-specific metadata
|
||||
*/
|
||||
#define COPY32(v, a) { \
|
||||
u_int32_t x = (v); \
|
||||
i386_copyin(&x, a, sizeof(x)); \
|
||||
a += sizeof(x); \
|
||||
}
|
||||
|
||||
#define MOD_STR(t, a, s) { \
|
||||
COPY32(t, a); \
|
||||
COPY32(strlen(s) + 1, a); \
|
||||
i386_copyin(s, a, strlen(s) + 1); \
|
||||
a += roundup(strlen(s) + 1, sizeof(u_long));\
|
||||
}
|
||||
|
||||
#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
|
||||
#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
|
||||
|
||||
#define MOD_VAR(t, a, s) { \
|
||||
COPY32(t, a); \
|
||||
COPY32(sizeof(s), a); \
|
||||
i386_copyin(&s, a, sizeof(s)); \
|
||||
a += roundup(sizeof(s), sizeof(u_long)); \
|
||||
}
|
||||
|
||||
#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
|
||||
#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
|
||||
|
||||
#define MOD_METADATA(a, mm) { \
|
||||
COPY32(MODINFO_METADATA | mm->md_type, a); \
|
||||
COPY32(mm->md_size, a); \
|
||||
i386_copyin(mm->md_data, a, mm->md_size); \
|
||||
a += roundup(mm->md_size, sizeof(u_long));\
|
||||
}
|
||||
|
||||
#define MOD_END(a) { \
|
||||
COPY32(MODINFO_END, a); \
|
||||
COPY32(0, a); \
|
||||
}
|
||||
|
||||
vm_offset_t
|
||||
bi_copymodules(vm_offset_t addr)
|
||||
{
|
||||
struct loaded_module *mp;
|
||||
struct module_metadata *md;
|
||||
|
||||
/* start with the first module on the list, should be the kernel */
|
||||
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
|
||||
|
||||
MOD_NAME(addr, mp->m_name); /* this field must come first */
|
||||
MOD_TYPE(addr, mp->m_type);
|
||||
MOD_ADDR(addr, mp->m_addr);
|
||||
MOD_SIZE(addr, mp->m_size);
|
||||
for (md = mp->m_metadata; md != NULL; md = md->md_next)
|
||||
if (!(md->md_type & MODINFOMD_NOCOPY))
|
||||
MOD_METADATA(addr, md);
|
||||
}
|
||||
MOD_END(addr);
|
||||
return(addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the information expected by an i386 kernel.
|
||||
*
|
||||
* - The 'boothowto' argument is constructed
|
||||
* - The 'botdev' argument is constructed
|
||||
* - The 'bootinfo' struct is constructed, and copied into the kernel space.
|
||||
* - The kernel environment is copied into kernel space.
|
||||
* - Module metadata are formatted and placed in kernel space.
|
||||
*/
|
||||
int
|
||||
bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
|
||||
{
|
||||
struct loaded_module *xp;
|
||||
struct i386_devdesc *rootdev;
|
||||
vm_offset_t addr, bootinfo_addr;
|
||||
char *rootdevname;
|
||||
int bootdevnr;
|
||||
u_int pad;
|
||||
char *kernelname;
|
||||
const char *kernelpath;
|
||||
#ifdef PC98
|
||||
int i;
|
||||
#endif
|
||||
|
||||
*howtop = bi_getboothowto(args);
|
||||
|
||||
/*
|
||||
* Allow the environment variable 'rootdev' to override the supplied device
|
||||
* This should perhaps go to MI code and/or have $rootdev tested/set by
|
||||
* MI code before launching the kernel.
|
||||
*/
|
||||
rootdevname = getenv("rootdev");
|
||||
i386_getdev((void **)(&rootdev), rootdevname, NULL);
|
||||
if (rootdev == NULL) { /* bad $rootdev/$currdev */
|
||||
printf("can't determine root device\n");
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
switch(rootdev->d_type) {
|
||||
case DEVT_DISK:
|
||||
/* pass in the BIOS device number of the current disk */
|
||||
bi.bi_bios_dev = bd_unit2bios(rootdev->d_kind.biosdisk.unit);
|
||||
bootdevnr = bd_getdev(rootdev);
|
||||
if (bootdevnr != -1)
|
||||
break;
|
||||
printf("root device %s invalid\n", i386_fmtdev(rootdev));
|
||||
return(EINVAL);
|
||||
|
||||
default:
|
||||
printf("aout_exec: WARNING - don't know how to boot from device type %d\n", rootdev->d_type);
|
||||
}
|
||||
free(rootdev);
|
||||
*bootdevp = bootdevnr;
|
||||
|
||||
/* legacy bootinfo structure */
|
||||
bi.bi_version = BOOTINFO_VERSION;
|
||||
bi.bi_kernelname = 0; /* XXX char * -> kernel name */
|
||||
bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */
|
||||
bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */
|
||||
/* bi.bi_bios_geom[] */
|
||||
#ifdef PC98
|
||||
for(i = 0; i < N_BIOS_GEOM; i++)
|
||||
bi.bi_bios_geom[i] = initial_bootinfo->bi_bios_geom[i];
|
||||
#endif
|
||||
bi.bi_size = sizeof(bi);
|
||||
bi.bi_memsizes_valid = 1;
|
||||
bi.bi_basemem = getbasemem();
|
||||
bi.bi_extmem = getextmem();
|
||||
|
||||
/* find the last module in the chain */
|
||||
addr = 0;
|
||||
for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) {
|
||||
if (addr < (xp->m_addr + xp->m_size))
|
||||
addr = xp->m_addr + xp->m_size;
|
||||
}
|
||||
/* pad to a page boundary */
|
||||
pad = (u_int)addr & PAGE_MASK;
|
||||
if (pad != 0) {
|
||||
pad = PAGE_SIZE - pad;
|
||||
addr += pad;
|
||||
}
|
||||
|
||||
/* copy our environment */
|
||||
bi.bi_envp = addr;
|
||||
addr = bi_copyenv(addr);
|
||||
|
||||
/* pad to a page boundary */
|
||||
pad = (u_int)addr & PAGE_MASK;
|
||||
if (pad != 0) {
|
||||
pad = PAGE_SIZE - pad;
|
||||
addr += pad;
|
||||
}
|
||||
/* copy module list and metadata */
|
||||
bi.bi_modulep = addr;
|
||||
addr = bi_copymodules(addr);
|
||||
|
||||
/* all done copying stuff in, save end of loaded object space */
|
||||
bi.bi_kernend = addr;
|
||||
|
||||
*howtop |= RB_BOOTINFO; /* it's there now */
|
||||
|
||||
/*
|
||||
* Get the kernel name, strip off any device prefix.
|
||||
*/
|
||||
kernelname = getenv("kernelname");
|
||||
i386_getdev(NULL, kernelname, &kernelpath);
|
||||
bi.bi_kernelname = VTOP(kernelpath);
|
||||
*bip = VTOP(&bi);
|
||||
|
||||
return(0);
|
||||
}
|
136
sys/boot/pc98/libpc98/comconsole.c
Normal file
136
sys/boot/pc98/libpc98/comconsole.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: comconsole.c,v 1.6 1999/01/10 14:48:05 rnordier Exp $
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
#include <bootstrap.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include "libi386.h"
|
||||
|
||||
/* selected defines from ns16550.h */
|
||||
#define com_data 0 /* data register (R/W) */
|
||||
#define com_dlbl 0 /* divisor latch low (W) */
|
||||
#define com_dlbh 1 /* divisor latch high (W) */
|
||||
#define com_ier 1 /* interrupt enable (W) */
|
||||
#define com_iir 2 /* interrupt identification (R) */
|
||||
#define com_fifo 2 /* FIFO control (W) */
|
||||
#define com_lctl 3 /* line control register (R/W) */
|
||||
#define com_cfcr 3 /* line control register (R/W) */
|
||||
#define com_mcr 4 /* modem control register (R/W) */
|
||||
#define com_lsr 5 /* line status register (R/W) */
|
||||
#define com_msr 6 /* modem status register (R/W) */
|
||||
|
||||
/* selected defines from sioreg.h */
|
||||
#define CFCR_DLAB 0x80
|
||||
#define MCR_RTS 0x02
|
||||
#define MCR_DTR 0x01
|
||||
#define LSR_TXRDY 0x20
|
||||
#define LSR_RXRDY 0x01
|
||||
|
||||
#define COMC_FMT 0x3 /* 8N1 */
|
||||
#define COMC_TXWAIT 0x40000 /* transmit timeout */
|
||||
#define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */
|
||||
|
||||
#ifndef COMPORT
|
||||
#ifdef PC98
|
||||
#define COMPORT 0x238
|
||||
#else
|
||||
#define COMPORT 0x3f8
|
||||
#endif
|
||||
#endif
|
||||
#ifndef COMSPEED
|
||||
#define COMSPEED 9600
|
||||
#endif
|
||||
|
||||
static void comc_probe(struct console *cp);
|
||||
static int comc_init(int arg);
|
||||
static void comc_putchar(int c);
|
||||
static int comc_getchar(void);
|
||||
static int comc_ischar(void);
|
||||
|
||||
static int comc_started;
|
||||
|
||||
struct console comconsole = {
|
||||
"comconsole",
|
||||
"serial port",
|
||||
0,
|
||||
comc_probe,
|
||||
comc_init,
|
||||
comc_putchar,
|
||||
comc_getchar,
|
||||
comc_ischar
|
||||
};
|
||||
|
||||
static void
|
||||
comc_probe(struct console *cp)
|
||||
{
|
||||
/* XXX check the BIOS equipment list? */
|
||||
cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_init(int arg)
|
||||
{
|
||||
if (comc_started && arg == 0)
|
||||
return 0;
|
||||
comc_started = 1;
|
||||
|
||||
outb(COMPORT + com_cfcr, CFCR_DLAB | COMC_FMT);
|
||||
outb(COMPORT + com_dlbl, COMC_BPS(COMSPEED) & 0xff);
|
||||
outb(COMPORT + com_dlbh, COMC_BPS(COMSPEED) >> 8);
|
||||
outb(COMPORT + com_cfcr, COMC_FMT);
|
||||
outb(COMPORT + com_mcr, MCR_RTS | MCR_DTR);
|
||||
|
||||
do
|
||||
inb(COMPORT + com_data);
|
||||
while (inb(COMPORT + com_lsr) & LSR_RXRDY);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
comc_putchar(int c)
|
||||
{
|
||||
int wait;
|
||||
|
||||
for (wait = COMC_TXWAIT; wait > 0; wait--)
|
||||
if (inb(COMPORT + com_lsr) & LSR_TXRDY) {
|
||||
outb(COMPORT + com_data, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
comc_getchar(void)
|
||||
{
|
||||
return(comc_ischar() ? inb(COMPORT + com_data) : -1);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_ischar(void)
|
||||
{
|
||||
return(inb(COMPORT + com_lsr) & LSR_RXRDY);
|
||||
}
|
57
sys/boot/pc98/libpc98/gatea20.c
Normal file
57
sys/boot/pc98/libpc98/gatea20.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* $Id: gatea20.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
|
||||
* From: $NetBSD: gatea20.c,v 1.2 1997/10/29 00:32:49 fvdl Exp $
|
||||
*/
|
||||
|
||||
/* extracted from freebsd:sys/i386/boot/biosboot/io.c */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
#include <stand.h>
|
||||
|
||||
#include "libi386.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()
|
||||
{
|
||||
__asm("pushfl ; cli");
|
||||
#ifdef PC98
|
||||
outb(0xf2, 0x00);
|
||||
outb(0xf6, 0x02);
|
||||
#else /* IBM PC */
|
||||
#ifdef IBM_L40
|
||||
outb(0x92, 0x2);
|
||||
#else IBM_L40
|
||||
while (inb(K_STATUS) & K_IBUF_FUL);
|
||||
while (inb(K_STATUS) & K_OBUF_FUL)
|
||||
(void)inb(K_RDWR);
|
||||
|
||||
outb(K_CMD, KC_CMD_WOUT);
|
||||
delay(100);
|
||||
while (inb(K_STATUS) & K_IBUF_FUL);
|
||||
outb(K_RDWR, x_20);
|
||||
delay(100);
|
||||
while (inb(K_STATUS) & K_IBUF_FUL);
|
||||
#endif IBM_L40
|
||||
#endif /* IBM PC */
|
||||
__asm("popfl");
|
||||
}
|
83
sys/boot/pc98/libpc98/time.c
Normal file
83
sys/boot/pc98/libpc98/time.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* mjs copyright
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
#include <btxv86.h>
|
||||
#ifdef PC98
|
||||
#include <machine/cpufunc.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the time in seconds since the beginning of the day.
|
||||
*
|
||||
* If we pass midnight, don't wrap back to 0.
|
||||
*
|
||||
* XXX uses undocumented BCD support from libstand.
|
||||
*/
|
||||
|
||||
time_t
|
||||
time(time_t *t)
|
||||
{
|
||||
static time_t lasttime, now;
|
||||
int hr, min, sec;
|
||||
#ifdef PC98
|
||||
unsigned char bios_time[6];
|
||||
#endif
|
||||
|
||||
v86.ctl = 0;
|
||||
#ifdef PC98
|
||||
v86.addr = 0x1c; /* int 0x1c, function 0 */
|
||||
v86.eax = 0x0000;
|
||||
v86.es = VTOPSEG(bios_time);
|
||||
v86.ebx = VTOPOFF(bios_time);
|
||||
#else
|
||||
v86.addr = 0x1a; /* int 0x1a, function 2 */
|
||||
v86.eax = 0x0200;
|
||||
#endif
|
||||
v86int();
|
||||
|
||||
#ifdef PC98
|
||||
hr = bcd2bin(bios_time[3]);
|
||||
min = bcd2bin(bios_time[4]);
|
||||
sec = bcd2bin(bios_time[5]);
|
||||
#else
|
||||
hr = bcd2bin((v86.ecx & 0xff00) >> 8); /* hour in %ch */
|
||||
min = bcd2bin(v86.ecx & 0xff); /* minute in %cl */
|
||||
sec = bcd2bin((v86.edx & 0xff00) >> 8); /* second in %dh */
|
||||
#endif
|
||||
|
||||
now = hr * 3600 + min * 60 + sec;
|
||||
if (now < lasttime)
|
||||
now += 24 * 3600;
|
||||
lasttime = now;
|
||||
|
||||
if (t != NULL)
|
||||
*t = now;
|
||||
return(now);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the BIOS Wait function to pause for (period) microseconds.
|
||||
*
|
||||
* Resolution of this function is variable, but typically around
|
||||
* 1ms.
|
||||
*/
|
||||
void
|
||||
delay(int period)
|
||||
{
|
||||
#ifdef PC98
|
||||
int i;
|
||||
period = (period + 500) / 1000;
|
||||
for( ; period != 0 ; period--)
|
||||
for(i=800;i != 0; i--)
|
||||
outb(0x5f,0); /* wait 600ns */
|
||||
#else
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x15; /* int 0x15, function 0x86 */
|
||||
v86.eax = 0x8600;
|
||||
v86.ecx = period >> 16;
|
||||
v86.edx = period & 0xffff;
|
||||
v86int();
|
||||
#endif
|
||||
}
|
800
sys/boot/pc98/libpc98/vidconsole.c
Normal file
800
sys/boot/pc98/libpc98/vidconsole.c
Normal file
@ -0,0 +1,800 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
|
||||
* Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
|
||||
* 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.
|
||||
*
|
||||
* From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
|
||||
*
|
||||
* $Id: vidconsole.c,v 1.11 1999/01/04 18:45:08 peter Exp $
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
#include <bootstrap.h>
|
||||
#include <btxv86.h>
|
||||
#include <machine/psl.h>
|
||||
#include "libi386.h"
|
||||
#ifdef PC98
|
||||
#include <machine/cpufunc.h>
|
||||
#endif
|
||||
|
||||
#if KEYBOARD_PROBE
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
static int probe_keyboard(void);
|
||||
#endif
|
||||
static void vidc_probe(struct console *cp);
|
||||
static int vidc_init(int arg);
|
||||
static void vidc_putchar(int c);
|
||||
static int vidc_getchar(void);
|
||||
static int vidc_ischar(void);
|
||||
|
||||
static int vidc_started;
|
||||
|
||||
#ifdef TERM_EMU
|
||||
void end_term();
|
||||
void bail_out(int c);
|
||||
void vidc_term_emu(int c);
|
||||
void get_pos(void);
|
||||
void curs_move(int x, int y);
|
||||
void write_char(int c, int fg, int bg);
|
||||
void scroll_up(int rows, int fg, int bg);
|
||||
void AB(void);
|
||||
void AF(void);
|
||||
void CD(void);
|
||||
void CM(void);
|
||||
void HO(void);
|
||||
void ME(void);
|
||||
|
||||
static int args[2],argc,br;
|
||||
static int fg,bg,dig;
|
||||
static int fg_c,bg_c,curx,cury;
|
||||
static int esc;
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
static unsigned short *crtat, *Crtat;
|
||||
static int row = 25, col = 80;
|
||||
#ifdef TERM_EMU
|
||||
unsigned int at2pc98(unsigned int fg_at, unsigned int bg_at);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct console vidconsole = {
|
||||
"vidconsole",
|
||||
"internal video/keyboard",
|
||||
0,
|
||||
vidc_probe,
|
||||
vidc_init,
|
||||
vidc_putchar,
|
||||
vidc_getchar,
|
||||
vidc_ischar
|
||||
};
|
||||
|
||||
static void
|
||||
vidc_probe(struct console *cp)
|
||||
{
|
||||
|
||||
/* look for a keyboard */
|
||||
#if KEYBOARD_PROBE
|
||||
if (probe_keyboard())
|
||||
#endif
|
||||
{
|
||||
|
||||
cp->c_flags |= C_PRESENTIN;
|
||||
}
|
||||
|
||||
/* XXX for now, always assume we can do BIOS screen output */
|
||||
cp->c_flags |= C_PRESENTOUT;
|
||||
}
|
||||
|
||||
static int
|
||||
vidc_init(int arg)
|
||||
{
|
||||
int i;
|
||||
#ifdef PC98
|
||||
int hw_cursor;
|
||||
#endif
|
||||
|
||||
if (vidc_started && arg == 0)
|
||||
return;
|
||||
vidc_started = 1;
|
||||
#ifdef PC98
|
||||
Crtat = (unsigned short *)PTOV(0xA0000);
|
||||
while((inb(0x60) & 0x04) == 0);
|
||||
outb(0x62, 0xe0);
|
||||
while((inb(0x60) & 0x01) == 0);
|
||||
hw_cursor = inb(0x62);
|
||||
hw_cursor |= (inb(0x62) << 8);
|
||||
inb(0x62);
|
||||
inb(0x62);
|
||||
inb(0x62);
|
||||
crtat = Crtat + hw_cursor;
|
||||
#endif
|
||||
#ifdef TERM_EMU
|
||||
/* Init terminal emulator */
|
||||
end_term();
|
||||
get_pos();
|
||||
curs_move(curx,cury);
|
||||
fg_c=7;
|
||||
bg_c=0;
|
||||
#endif
|
||||
for(i = 0; i < 10 && vidc_ischar(); i++)
|
||||
(void)vidc_getchar();
|
||||
return(0); /* XXX reinit? */
|
||||
}
|
||||
|
||||
static void
|
||||
vidc_biosputchar(int c)
|
||||
{
|
||||
#ifdef PC98
|
||||
unsigned short *cp;
|
||||
int i, pos;
|
||||
|
||||
#ifdef TERM_EMU
|
||||
*crtat = (c == 0x5c ? 0xfc : c);
|
||||
*(crtat + 0x1000) = at2pc98(fg, bg);
|
||||
#else
|
||||
switch(c) {
|
||||
case '\b':
|
||||
crtat--;
|
||||
break;
|
||||
case '\r':
|
||||
crtat -= (crtat - Crtat) % col;
|
||||
break;
|
||||
case '\n':
|
||||
crtat += col;
|
||||
break;
|
||||
default:
|
||||
*crtat = (c == 0x5c ? 0xfc : c);
|
||||
*(crtat++ + 0x1000) = 0xe1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (crtat >= Crtat + col * row) {
|
||||
cp = Crtat;
|
||||
for (i = 1; i < row; i++) {
|
||||
bcopy((void *)(cp+col), (void *)cp, col*2);
|
||||
cp += col;
|
||||
}
|
||||
for (i = 0; i < col; i++) {
|
||||
*cp++ = ' ';
|
||||
}
|
||||
crtat -= col;
|
||||
}
|
||||
pos = crtat - Crtat;
|
||||
while((inb(0x60) & 0x04) == 0) {}
|
||||
outb(0x62, 0x49);
|
||||
outb(0x60, pos & 0xff);
|
||||
outb(0x60, pos >> 8);
|
||||
#endif
|
||||
#else
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x10;
|
||||
v86.eax = 0xe00 | (c & 0xff);
|
||||
v86.ebx = 0x7;
|
||||
v86int();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
vidc_rawputchar(int c)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(c == '\t')
|
||||
/* lame tab expansion */
|
||||
for (i = 0; i < 8; i++)
|
||||
vidc_rawputchar(' ');
|
||||
else {
|
||||
#ifndef TERM_EMU
|
||||
vidc_biosputchar(c);
|
||||
#else
|
||||
/* Emulate AH=0eh (teletype output) */
|
||||
switch(c) {
|
||||
case '\a':
|
||||
vidc_biosputchar(c);
|
||||
return;
|
||||
case '\r':
|
||||
curx=0;
|
||||
curs_move(curx,cury);
|
||||
return;
|
||||
case '\n':
|
||||
cury++;
|
||||
if(cury>24) {
|
||||
scroll_up(1,fg_c,bg_c);
|
||||
cury--;
|
||||
} else {
|
||||
curs_move(curx,cury);
|
||||
}
|
||||
return;
|
||||
case '\b':
|
||||
if(curx>0) {
|
||||
curx--;
|
||||
curs_move(curx,cury);
|
||||
/* write_char(' ',fg_c,bg_c); XXX destructive(!) */
|
||||
return;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
write_char(c,fg_c,bg_c);
|
||||
curx++;
|
||||
if(curx>79) {
|
||||
curx=0;
|
||||
cury++;
|
||||
}
|
||||
if(cury>24) {
|
||||
curx=0;
|
||||
scroll_up(1,fg_c,bg_c);
|
||||
cury--;
|
||||
}
|
||||
}
|
||||
curs_move(curx,cury);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TERM_EMU
|
||||
|
||||
/* Get cursor position on the screen. Result is in edx. Sets
|
||||
* curx and cury appropriately.
|
||||
*/
|
||||
void
|
||||
get_pos(void)
|
||||
{
|
||||
#ifdef PC98
|
||||
int pos = crtat - Crtat;
|
||||
curx = pos % col;
|
||||
cury = pos / col;
|
||||
#else
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x10;
|
||||
v86.eax = 0x0300;
|
||||
v86.ebx = 0x0;
|
||||
v86int();
|
||||
curx=v86.edx & 0x00ff;
|
||||
cury=(v86.edx & 0xff00)>>8;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Move cursor to x rows and y cols (0-based). */
|
||||
void
|
||||
curs_move(int x, int y)
|
||||
{
|
||||
#ifdef PC98
|
||||
int pos;
|
||||
pos = x + y*col;
|
||||
crtat = Crtat + pos;
|
||||
pos = crtat - Crtat;
|
||||
while((inb(0x60) & 0x04) == 0) {}
|
||||
outb(0x62, 0x49);
|
||||
outb(0x60, pos & 0xff);
|
||||
outb(0x60, pos >> 8);
|
||||
curx=x;
|
||||
cury=y;
|
||||
#define isvisible(c) (((c)>32) && ((c)<255))
|
||||
if(!isvisible(*crtat & 0x00ff)) {
|
||||
write_char(' ',fg_c,bg_c);
|
||||
}
|
||||
#else
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x10;
|
||||
v86.eax = 0x0200;
|
||||
v86.ebx = 0x0;
|
||||
v86.edx = ((0x00ff & y)<<8)+(0x00ff & x);
|
||||
v86int();
|
||||
curx=x;
|
||||
cury=y;
|
||||
/* If there is ctrl char at this position, cursor would be invisible.
|
||||
* Make it a space instead.
|
||||
*/
|
||||
v86.ctl=0;
|
||||
v86.addr = 0x10;
|
||||
v86.eax = 0x0800;
|
||||
v86.ebx= 0x0;
|
||||
v86int();
|
||||
#define isvisible(c) (((c)>32) && ((c)<255))
|
||||
if(!isvisible(v86.eax & 0x00ff)) {
|
||||
write_char(' ',fg_c,bg_c);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Scroll up the whole window by a number of rows. If rows==0,
|
||||
* clear the window. fg and bg are attributes for the new lines
|
||||
* inserted in the window.
|
||||
*/
|
||||
void
|
||||
scroll_up(int rows, int fg, int bg)
|
||||
{
|
||||
#ifdef PC98
|
||||
unsigned short *cp;
|
||||
int i;
|
||||
|
||||
if(rows==0) rows=25;
|
||||
cp = Crtat;
|
||||
for (i = rows ; i < row; i++) {
|
||||
bcopy((void *)(cp+col), (void *)cp, col*2);
|
||||
cp += col;
|
||||
}
|
||||
for (i = 0; i < col; i++) {
|
||||
*(cp + 0x1000) = at2pc98(fg, bg);
|
||||
*cp++ = ' ';
|
||||
}
|
||||
#else
|
||||
if(rows==0) rows=25;
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x10;
|
||||
v86.eax = 0x0600+(0x00ff & rows);
|
||||
v86.ebx = (bg<<12)+(fg<<8);
|
||||
v86.ecx = 0x0;
|
||||
v86.edx = 0x184f;
|
||||
v86int();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Write character and attribute at cursor position. */
|
||||
void
|
||||
write_char(int c, int fg, int bg)
|
||||
{
|
||||
#ifdef PC98
|
||||
*crtat = c;
|
||||
*(crtat + 0x1000) = at2pc98(fg, bg);
|
||||
#else
|
||||
v86.ctl=0;
|
||||
v86.addr = 0x10;
|
||||
v86.eax = 0x0900+(0x00ff & c);
|
||||
v86.ebx = (bg<<4)+fg;
|
||||
v86.ecx = 0x1;
|
||||
v86int();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Calculate power of 10 */
|
||||
int
|
||||
pow10(int i)
|
||||
{
|
||||
int res=1;
|
||||
|
||||
while(i-->0) {
|
||||
res*=10;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/*
|
||||
* Screen manipulation functions. They use accumulated data in
|
||||
* args[] and argc variables.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Set background color */
|
||||
void
|
||||
AB(void){
|
||||
bg_c=args[0];
|
||||
end_term();
|
||||
}
|
||||
|
||||
/* Set foreground color */
|
||||
void
|
||||
AF(void)
|
||||
{
|
||||
fg_c=args[0];
|
||||
end_term();
|
||||
}
|
||||
|
||||
/* Clear display from current position to end of screen */
|
||||
void
|
||||
CD(void)
|
||||
{
|
||||
get_pos();
|
||||
#ifdef PC98
|
||||
for(;crtat <= Crtat + col*row; crtat++){
|
||||
*crtat = ' ';
|
||||
*(crtat + 0x1000) = at2pc98(fg_c, bg_c);
|
||||
}
|
||||
#else
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x10;
|
||||
v86.eax = 0x0600;
|
||||
v86.ebx = (bg_c<<4)+fg_c;
|
||||
v86.ecx = v86.edx;
|
||||
v86.edx = 0x184f;
|
||||
v86int();
|
||||
#endif
|
||||
curx=0;
|
||||
curs_move(curx,cury);
|
||||
end_term();
|
||||
}
|
||||
|
||||
/* Absolute cursor move to args[0] rows and args[1] columns
|
||||
* (the coordinates are 1-based).
|
||||
*/
|
||||
void
|
||||
CM(void)
|
||||
{
|
||||
if(args[0]>0) args[0]--;
|
||||
if(args[1]>0) args[1]--;
|
||||
curs_move(args[1],args[0]);
|
||||
end_term();
|
||||
}
|
||||
|
||||
/* Home cursor (left top corner) */
|
||||
void
|
||||
HO(void)
|
||||
{
|
||||
argc=1;
|
||||
args[0]=args[1]=1;
|
||||
CM();
|
||||
}
|
||||
|
||||
/* Exit attribute mode (reset fore/back-ground colors to defaults) */
|
||||
void
|
||||
ME(void)
|
||||
{
|
||||
fg_c=7;
|
||||
bg_c=0;
|
||||
end_term();
|
||||
}
|
||||
|
||||
/* Clear internal state of the terminal emulation code */
|
||||
void
|
||||
end_term(void)
|
||||
{
|
||||
esc=0;
|
||||
argc=-1;
|
||||
fg=bg=br=0;
|
||||
args[0]=args[1]=0;
|
||||
dig=0;
|
||||
}
|
||||
|
||||
/* Gracefully exit ESC-sequence processing in case of misunderstanding */
|
||||
void
|
||||
bail_out(int c)
|
||||
{
|
||||
char buf[6],*ch;
|
||||
|
||||
if(esc) vidc_rawputchar('\033');
|
||||
if(br) vidc_rawputchar('[');
|
||||
if(argc>-1) {
|
||||
sprintf(buf,"%d",args[0]);
|
||||
ch=buf;
|
||||
while(*ch) vidc_rawputchar(*ch++);
|
||||
|
||||
if(argc>0) {
|
||||
vidc_rawputchar(';');
|
||||
sprintf(buf,"%d",args[1]);
|
||||
ch=buf;
|
||||
while(*ch) vidc_rawputchar(*ch++);
|
||||
}
|
||||
}
|
||||
vidc_rawputchar(c);
|
||||
end_term();
|
||||
}
|
||||
|
||||
/* Emulate basic capabilities of cons25 terminal */
|
||||
void
|
||||
vidc_term_emu(int c)
|
||||
{
|
||||
|
||||
if(!esc) {
|
||||
if(c=='\033') {
|
||||
esc=1;
|
||||
} else {
|
||||
vidc_rawputchar(c);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do ESC sequences processing */
|
||||
switch(c) {
|
||||
case '\033':
|
||||
/* ESC in ESC sequence - error */
|
||||
bail_out(c);
|
||||
break;
|
||||
case '[':
|
||||
/* Check if it's first char after ESC */
|
||||
if(argc<0) {
|
||||
br=1;
|
||||
} else {
|
||||
bail_out(c);
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
/* Emulate \E[H (cursor home) and
|
||||
* \E%d;%dH (cursor absolute move) */
|
||||
if(br) {
|
||||
switch(argc) {
|
||||
case -1:
|
||||
HO();
|
||||
break;
|
||||
case 1:
|
||||
if(fg) args[0]+=pow10(dig)*3;
|
||||
if(bg) args[0]+=pow10(dig)*4;
|
||||
CM();
|
||||
break;
|
||||
default:
|
||||
bail_out(c);
|
||||
}
|
||||
} else bail_out(c);
|
||||
break;
|
||||
case 'J':
|
||||
/* Emulate \EJ (clear to end of screen) */
|
||||
if(br && argc<0) {
|
||||
CD();
|
||||
} else bail_out(c);
|
||||
break;
|
||||
case ';':
|
||||
/* perhaps args separator */
|
||||
if(br && (argc>-1)) {
|
||||
argc++;
|
||||
} else bail_out(c);
|
||||
break;
|
||||
case 'm':
|
||||
/* Change char attributes */
|
||||
if(br) {
|
||||
switch(argc) {
|
||||
case -1:
|
||||
ME();
|
||||
break;
|
||||
case 0:
|
||||
if(fg) AF();
|
||||
else AB();
|
||||
break;
|
||||
default:
|
||||
bail_out(c);
|
||||
}
|
||||
} else bail_out(c);
|
||||
break;
|
||||
default:
|
||||
if(isdigit(c)) {
|
||||
/* Carefully collect numeric arguments */
|
||||
/* XXX this is ugly. */
|
||||
if(br) {
|
||||
if(argc==-1) {
|
||||
argc=0;
|
||||
args[argc]=0;
|
||||
dig=0;
|
||||
/* in case we're in error... */
|
||||
if(c=='3') {
|
||||
fg=1;
|
||||
return;
|
||||
}
|
||||
if(c=='4') {
|
||||
bg=1;
|
||||
return;
|
||||
}
|
||||
args[argc]=(int)(c-'0');
|
||||
dig=1;
|
||||
args[argc+1]=0;
|
||||
} else {
|
||||
args[argc]=args[argc]*10+(int)(c-'0');
|
||||
if(argc==0) dig++;
|
||||
}
|
||||
} else bail_out(c);
|
||||
} else bail_out(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
vidc_putchar(int c)
|
||||
{
|
||||
#ifdef TERM_EMU
|
||||
vidc_term_emu(c);
|
||||
#else
|
||||
vidc_rawputchar(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
vidc_getchar(void)
|
||||
{
|
||||
if (vidc_ischar()) {
|
||||
v86.ctl = 0;
|
||||
#ifdef PC98
|
||||
v86.addr = 0x18;
|
||||
#else
|
||||
v86.addr = 0x16;
|
||||
#endif
|
||||
v86.eax = 0x0;
|
||||
v86int();
|
||||
return(v86.eax & 0xff);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vidc_ischar(void)
|
||||
{
|
||||
#ifdef PC98
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x18;
|
||||
v86.eax = 0x100;
|
||||
v86int();
|
||||
return((v86.ebx >> 8) & 0x1);
|
||||
#else
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.addr = 0x16;
|
||||
v86.eax = 0x100;
|
||||
v86int();
|
||||
return(!(v86.efl & PSL_Z));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if KEYBOARD_PROBE
|
||||
#ifdef PC98
|
||||
static int
|
||||
probe_keyboard(void)
|
||||
{
|
||||
return (*(u_char *)PTOV(0xA1481) & 0x48);
|
||||
}
|
||||
#else /* PC98 */
|
||||
#define PROBE_MAXRETRY 5
|
||||
#define PROBE_MAXWAIT 400
|
||||
#define IO_DUMMY 0x84
|
||||
#define IO_KBD 0x060 /* 8042 Keyboard */
|
||||
|
||||
/* selected defines from kbdio.h */
|
||||
#define KBD_STATUS_PORT 4 /* status port, read */
|
||||
#define KBD_DATA_PORT 0 /* data port, read/write
|
||||
* also used as keyboard command
|
||||
* and mouse command port
|
||||
*/
|
||||
#define KBDC_ECHO 0x00ee
|
||||
#define KBDS_ANY_BUFFER_FULL 0x0001
|
||||
#define KBDS_INPUT_BUFFER_FULL 0x0002
|
||||
#define KBD_ECHO 0x00ee
|
||||
|
||||
/* 7 microsec delay necessary for some keyboard controllers */
|
||||
static void
|
||||
delay7(void)
|
||||
{
|
||||
/*
|
||||
* I know this is broken, but no timer is available yet at this stage...
|
||||
* See also comments in `delay1ms()'.
|
||||
*/
|
||||
inb(IO_DUMMY); inb(IO_DUMMY);
|
||||
inb(IO_DUMMY); inb(IO_DUMMY);
|
||||
inb(IO_DUMMY); inb(IO_DUMMY);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine uses an inb to an unused port, the time to execute that
|
||||
* inb is approximately 1.25uS. This value is pretty constant across
|
||||
* all CPU's and all buses, with the exception of some PCI implentations
|
||||
* that do not forward this I/O adress to the ISA bus as they know it
|
||||
* is not a valid ISA bus address, those machines execute this inb in
|
||||
* 60 nS :-(.
|
||||
*
|
||||
*/
|
||||
static void
|
||||
delay1ms(void)
|
||||
{
|
||||
int i = 800;
|
||||
while (--i >= 0)
|
||||
(void)inb(0x84);
|
||||
}
|
||||
|
||||
/*
|
||||
* We use the presence/absence of a keyboard to determine whether the internal
|
||||
* console can be used for input.
|
||||
*
|
||||
* Perform a simple test on the keyboard; issue the ECHO command and see
|
||||
* if the right answer is returned. We don't do anything as drastic as
|
||||
* full keyboard reset; it will be too troublesome and take too much time.
|
||||
*/
|
||||
static int
|
||||
probe_keyboard(void)
|
||||
{
|
||||
int retry = PROBE_MAXRETRY;
|
||||
int wait;
|
||||
int i;
|
||||
|
||||
while (--retry >= 0) {
|
||||
/* flush any noise */
|
||||
while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
|
||||
delay7();
|
||||
inb(IO_KBD + KBD_DATA_PORT);
|
||||
delay1ms();
|
||||
}
|
||||
|
||||
/* wait until the controller can accept a command */
|
||||
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
|
||||
if (((i = inb(IO_KBD + KBD_STATUS_PORT))
|
||||
& (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0)
|
||||
break;
|
||||
if (i & KBDS_ANY_BUFFER_FULL) {
|
||||
delay7();
|
||||
inb(IO_KBD + KBD_DATA_PORT);
|
||||
}
|
||||
delay1ms();
|
||||
}
|
||||
if (wait <= 0)
|
||||
continue;
|
||||
|
||||
/* send the ECHO command */
|
||||
outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO);
|
||||
|
||||
/* wait for a response */
|
||||
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
|
||||
if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL)
|
||||
break;
|
||||
delay1ms();
|
||||
}
|
||||
if (wait <= 0)
|
||||
continue;
|
||||
|
||||
delay7();
|
||||
i = inb(IO_KBD + KBD_DATA_PORT);
|
||||
#ifdef PROBE_KBD_BEBUG
|
||||
printf("probe_keyboard: got 0x%x.\n", i);
|
||||
#endif
|
||||
if (i == KBD_ECHO) {
|
||||
/* got the right answer */
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
#endif /* KEYBOARD_PROBE */
|
||||
|
||||
#ifdef TERM_EMU
|
||||
#ifdef PC98
|
||||
static u_char ibmpc_to_pc98[16] =
|
||||
{ 0x01,0x21,0x81,0xa1,0x41,0x61,0xc1,0xe1, 0x09,0x29,0x89,0xa9,0x49,0x69,0xc9,0xe9 };
|
||||
static u_char ibmpc_to_pc98rev[16] =
|
||||
{ 0x05,0x25,0x85,0xa5,0x45,0x65,0xc5,0xe5, 0x0d,0x2d,0x8d,0xad,0x4d,0x6d,0xcd,0xed };
|
||||
|
||||
unsigned int
|
||||
at2pc98(unsigned int fg_at, unsigned int bg_at)
|
||||
{
|
||||
unsigned int at;
|
||||
|
||||
if (bg_at) {
|
||||
if (bg_at & 0x80) {
|
||||
if (bg_at & 0x70) {
|
||||
/* reverse & blink */
|
||||
at = ibmpc_to_pc98rev[bg_at >> 4] | 0x02;
|
||||
} else {
|
||||
/* normal & blink */
|
||||
at = ibmpc_to_pc98[fg_at] | 0x02;
|
||||
}
|
||||
} else {
|
||||
/* reverse */
|
||||
at = ibmpc_to_pc98rev[bg_at >> 4];
|
||||
}
|
||||
} else {
|
||||
/* normal */
|
||||
at = ibmpc_to_pc98[fg_at];
|
||||
}
|
||||
at |= ((fg_at|bg_at) << 8);
|
||||
return (at);
|
||||
}
|
||||
#endif
|
||||
#endif
|
117
sys/boot/pc98/loader/Makefile
Normal file
117
sys/boot/pc98/loader/Makefile
Normal file
@ -0,0 +1,117 @@
|
||||
# $Id: Makefile,v 1.28 1999/01/18 19:05:27 msmith Exp $
|
||||
|
||||
BASE= loader
|
||||
PROG= ${BASE}
|
||||
NOMAN=
|
||||
STRIP=
|
||||
NEWVERSWHAT= "bootstrap loader"
|
||||
BINDIR?= /boot
|
||||
|
||||
CFLAGS+= -DPC98
|
||||
|
||||
# architecture-specific loader code
|
||||
SRCS= main.c conf.c
|
||||
.PATH: ${.CURDIR}/../../i386/loader
|
||||
|
||||
# Enable PnP and ISA-PnP code.
|
||||
HAVE_PNP= yes
|
||||
HAVE_ISABUS= yes
|
||||
|
||||
# Enable BootForth
|
||||
BOOT_FORTH= yes
|
||||
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl
|
||||
.if exists(${.OBJDIR}/../../ficl/libficl.a)
|
||||
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
|
||||
.else
|
||||
LIBFICL= ${.CURDIR}/../../ficl/libficl.a
|
||||
.endif
|
||||
|
||||
# Always add MI sources
|
||||
.PATH: ${.CURDIR}/../../common
|
||||
.include <${.CURDIR}/../../common/Makefile.inc>
|
||||
CFLAGS+= -I${.CURDIR}/../../common
|
||||
CFLAGS+= -I${.CURDIR}/../../.. -I. -I${.CURDIR}/../../i386
|
||||
|
||||
CLEANFILES+= vers.c vers.o ${BASE}.list ${BASE}.bin ${BASE}.sym ${BASE}.help
|
||||
|
||||
CFLAGS+= -Wall
|
||||
LDFLAGS= -nostdlib -static -Ttext 0x1000
|
||||
|
||||
# pc98 standalone support library
|
||||
LIBPC98= ${.OBJDIR}/../libpc98/libpc98.a
|
||||
CFLAGS+= -I${.CURDIR}/..
|
||||
|
||||
# where to get libstand from
|
||||
LIBSTAND= -lstand
|
||||
#LIBSTAND= ${.CURDIR}/../../../lib/libstand/libstand.a
|
||||
#CFLAGS+= -I${.CURDIR}/../../../lib/libstand/
|
||||
|
||||
# BTX components
|
||||
.if exists(${.OBJDIR}/../btx)
|
||||
BTXDIR= ${.OBJDIR}/../btx
|
||||
.else
|
||||
BTXDIR= ${.CURDIR}/../btx
|
||||
.endif
|
||||
BTXLDR= ${BTXDIR}/btxldr/btxldr
|
||||
BTXKERN= ${BTXDIR}/btx/btx
|
||||
BTXCRT= ${BTXDIR}/lib/crt0.o
|
||||
CFLAGS+= -I${.CURDIR}/../btx/lib
|
||||
|
||||
# BTX is expecting ELF components
|
||||
CFLAGS+= -elf
|
||||
|
||||
# New linker set code
|
||||
CFLAGS+= -DNEW_LINKER_SET
|
||||
|
||||
# Debug me!
|
||||
#CFLAGS+= -g
|
||||
#LDFLAGS+= -g
|
||||
|
||||
vers.o:
|
||||
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
|
||||
${CC} -c vers.c
|
||||
|
||||
${BASE}: ${BASE}.bin ${BTXLDR} ${BTXKERN} ${BTXCRT} ${BASE}.help
|
||||
btxld -v -f aout -e 0x100000 -o ${.TARGET} -l ${BTXLDR} -b ${BTXKERN} \
|
||||
${BASE}.bin
|
||||
# /usr/bin/kzip ${.TARGET}
|
||||
# mv ${.TARGET}.kz ${.TARGET}
|
||||
|
||||
${BASE}.bin: ${BASE}.sym
|
||||
cp ${.ALLSRC} ${.TARGET}
|
||||
strip ${.TARGET}
|
||||
|
||||
${BASE}.help: help.common help.pc98
|
||||
cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
|
||||
|
||||
beforeinstall:
|
||||
.if exists(${DESTDIR}/boot/loader)
|
||||
mv ${DESTDIR}/boot/loader ${DESTDIR}/boot/loader.old
|
||||
.endif
|
||||
.if exists(${.OBJDIR}/loader.help)
|
||||
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||
${.OBJDIR}/${BASE}.help ${DESTDIR}/boot
|
||||
.else
|
||||
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||
${.CURDIR}/${BASE}.help ${DESTDIR}/boot
|
||||
.endif
|
||||
|
||||
# Cannot use ${OBJS} above this line
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
${BASE}.sym: ${OBJS} ${LIBPC98} ${LIBSTAND} ${LIBFICL} vers.o
|
||||
${CC} ${LDFLAGS} -o ${.TARGET} ${BTXCRT} ${OBJS} vers.o \
|
||||
${LIBFICL} ${LIBSTAND} ${LIBPC98} ${LIBSTAND}
|
||||
|
||||
# If it's not there, don't consider it a target
|
||||
.if exists(${.CURDIR}/../../../i386/include)
|
||||
beforedepend ${OBJS}: machine
|
||||
|
||||
machine:
|
||||
ln -sf ${.CURDIR}/../../../i386/include machine
|
||||
|
||||
.endif
|
||||
|
||||
CLEANFILES+= machine
|
||||
|
||||
|
46
sys/boot/pc98/loader/help.pc98
Normal file
46
sys/boot/pc98/loader/help.pc98
Normal file
@ -0,0 +1,46 @@
|
||||
################################################################################
|
||||
# Treboot DReboot the system
|
||||
|
||||
reboot
|
||||
|
||||
Causes the system to immediately reboot.
|
||||
|
||||
################################################################################
|
||||
# Theap DDisplay memory management statistics
|
||||
|
||||
heap
|
||||
|
||||
Requests debugging output from the heap manager. For debugging use
|
||||
only.
|
||||
|
||||
################################################################################
|
||||
# Tset Snum_ide_disks DSet the number of IDE disks
|
||||
|
||||
NOTE: this variable is deprecated, use root_disk_unit instead.
|
||||
|
||||
set num_ide_disks=<value>
|
||||
|
||||
When booting from a SCSI disk on a system with one or more IDE disks,
|
||||
and where the IDE disks are the default boot device, it is necessary
|
||||
to tell the kernel how many IDE disks there are in order to have it
|
||||
correctly locate the SCSI disk you are booting from.
|
||||
|
||||
################################################################################
|
||||
# Tset Sboot_userconfig DStart Userconfig
|
||||
|
||||
set boot_userconfig
|
||||
|
||||
Requests that the kernel's interactive device configuration program
|
||||
be run when the kernel is booted.
|
||||
|
||||
################################################################################
|
||||
# Tset Sroot_disk_unit DForce the root disk unit number.
|
||||
|
||||
set root_disk_unit=<value>
|
||||
|
||||
If the code which detects the disk unit number for the root disk is
|
||||
confused, eg. by a mix of SCSI and IDE disks, or IDE disks with
|
||||
gaps in the sequence (eg. no primary slave), the unit number can be
|
||||
forced by setting this variable.
|
||||
|
||||
################################################################################
|
244
sys/boot/pc98/loader/main.c
Normal file
244
sys/boot/pc98/loader/main.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
|
||||
* 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.
|
||||
*
|
||||
* $Id: main.c,v 1.14 1998/11/02 23:28:11 msmith Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* MD bootstrap main() and assorted miscellaneous
|
||||
* commands.
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
#include <string.h>
|
||||
#include <machine/bootinfo.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "../../i386/libi386/libi386.h"
|
||||
#include "btxv86.h"
|
||||
|
||||
/* Arguments passed in from the boot1/boot2 loader */
|
||||
static struct
|
||||
{
|
||||
u_int32_t howto;
|
||||
u_int32_t bootdev;
|
||||
u_int32_t res0;
|
||||
u_int32_t res1;
|
||||
u_int32_t res2;
|
||||
u_int32_t bootinfo;
|
||||
} *kargs;
|
||||
|
||||
static u_int32_t initial_howto;
|
||||
static u_int32_t initial_bootdev;
|
||||
#ifdef PC98
|
||||
struct bootinfo *initial_bootinfo;
|
||||
#else
|
||||
static struct bootinfo *initial_bootinfo;
|
||||
#endif
|
||||
|
||||
struct arch_switch archsw; /* MI/MD interface boundary */
|
||||
|
||||
static void extract_currdev(void);
|
||||
static int isa_inb(int port);
|
||||
static void isa_outb(int port, int value);
|
||||
|
||||
/* from vers.c */
|
||||
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
|
||||
|
||||
/* XXX debugging */
|
||||
extern char end[];
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Pick up arguments */
|
||||
kargs = (void *)__args;
|
||||
initial_howto = kargs->howto;
|
||||
initial_bootdev = kargs->bootdev;
|
||||
initial_bootinfo = (struct bootinfo *)PTOV(kargs->bootinfo);
|
||||
|
||||
/*
|
||||
* Initialise the heap as early as possible. Once this is done, malloc() is usable.
|
||||
*
|
||||
* XXX better to locate end of memory and use that
|
||||
*/
|
||||
setheap((void *)end, (void *)(end + (384 * 1024)));
|
||||
|
||||
/*
|
||||
* XXX Chicken-and-egg problem; we want to have console output early, but some
|
||||
* console attributes may depend on reading from eg. the boot device, which we
|
||||
* can't do yet.
|
||||
*
|
||||
* We can use printf() etc. once this is done.
|
||||
* If the previous boot stage has requested a serial console, prefer that.
|
||||
*/
|
||||
if (initial_howto & RB_SERIAL)
|
||||
setenv("console", "comconsole", 1);
|
||||
cons_probe();
|
||||
|
||||
/*
|
||||
* Initialise the block cache
|
||||
*/
|
||||
bcache_init(32, 512); /* 16k cache XXX tune this */
|
||||
|
||||
/*
|
||||
* March through the device switch probing for things.
|
||||
*/
|
||||
for (i = 0; devsw[i] != NULL; i++)
|
||||
if (devsw[i]->dv_init != NULL)
|
||||
(devsw[i]->dv_init)();
|
||||
|
||||
printf("\n");
|
||||
printf("%s, Revision %s %d/%dkB\n", bootprog_name, bootprog_rev, getbasemem(), getextmem());
|
||||
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
|
||||
|
||||
extract_currdev(); /* set $currdev and $loaddev */
|
||||
setenv("LINES", "24", 1); /* optional */
|
||||
|
||||
archsw.arch_autoload = i386_autoload;
|
||||
archsw.arch_getdev = i386_getdev;
|
||||
archsw.arch_copyin = i386_copyin;
|
||||
archsw.arch_copyout = i386_copyout;
|
||||
archsw.arch_readin = i386_readin;
|
||||
archsw.arch_isainb = isa_inb;
|
||||
archsw.arch_isaoutb = isa_outb;
|
||||
|
||||
interact(); /* doesn't return */
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the 'current device' by (if possible) recovering the boot device as
|
||||
* supplied by the initial bootstrap.
|
||||
*
|
||||
* XXX should be extended for netbooting.
|
||||
*/
|
||||
static void
|
||||
extract_currdev(void)
|
||||
{
|
||||
struct i386_devdesc currdev;
|
||||
int major, biosdev;
|
||||
|
||||
/* We're booting from a BIOS disk, try to spiff this */
|
||||
currdev.d_dev = devsw[0]; /* XXX presumes that biosdisk is first in devsw */
|
||||
currdev.d_type = currdev.d_dev->dv_type;
|
||||
|
||||
if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
|
||||
/* The passed-in boot device is bad */
|
||||
currdev.d_kind.biosdisk.slice = -1;
|
||||
currdev.d_kind.biosdisk.partition = 0;
|
||||
biosdev = -1;
|
||||
} else {
|
||||
currdev.d_kind.biosdisk.slice = (B_ADAPTOR(initial_bootdev) << 4) + B_CONTROLLER(initial_bootdev) - 1;
|
||||
currdev.d_kind.biosdisk.partition = B_PARTITION(initial_bootdev);
|
||||
biosdev = initial_bootinfo->bi_bios_dev;
|
||||
major = B_TYPE(initial_bootdev);
|
||||
|
||||
/*
|
||||
* If we are booted by an old bootstrap, we have to guess at the BIOS
|
||||
* unit number. We will loose if there is more than one disk type
|
||||
* and we are not booting from the lowest-numbered disk type
|
||||
* (ie. SCSI when IDE also exists).
|
||||
*/
|
||||
#ifdef PC98
|
||||
if (major == 6)
|
||||
biosdev = 0x30 + B_UNIT(initial_bootdev);
|
||||
else
|
||||
biosdev = (major << 3) + 0x80 + B_UNIT(initial_bootdev);
|
||||
#else
|
||||
if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2)) /* biosdev doesn't match major */
|
||||
biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((currdev.d_kind.biosdisk.unit = bd_bios2unit(biosdev)) == -1) {
|
||||
printf("Can't work out which disk we are booting from.\n"
|
||||
"Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
|
||||
currdev.d_kind.biosdisk.unit = 0;
|
||||
}
|
||||
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev), i386_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset, env_nounset);
|
||||
}
|
||||
|
||||
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
|
||||
|
||||
static int
|
||||
command_reboot(int argc, char *argv[])
|
||||
{
|
||||
|
||||
printf("Rebooting...\n");
|
||||
delay(1000000);
|
||||
__exit(0);
|
||||
}
|
||||
|
||||
/* provide this for panic, as it's not in the startup code */
|
||||
void
|
||||
exit(int code)
|
||||
{
|
||||
__exit(code);
|
||||
}
|
||||
|
||||
COMMAND_SET(heap, "heap", "show heap usage", command_heap);
|
||||
|
||||
static int
|
||||
command_heap(int argc, char *argv[])
|
||||
{
|
||||
mallocstats();
|
||||
printf("heap base at %p, top at %p\n", end, sbrk(0));
|
||||
return(CMD_OK);
|
||||
}
|
||||
|
||||
/* ISA bus access functions for PnP, derived from <machine/cpufunc.h> */
|
||||
static int
|
||||
isa_inb(int port)
|
||||
{
|
||||
u_char data;
|
||||
|
||||
if (__builtin_constant_p(port) &&
|
||||
(((port) & 0xffff) < 0x100) &&
|
||||
((port) < 0x10000)) {
|
||||
__asm __volatile("inb %1,%0" : "=a" (data) : "id" ((u_short)(port)));
|
||||
} else {
|
||||
__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
|
||||
}
|
||||
return(data);
|
||||
}
|
||||
|
||||
static void
|
||||
isa_outb(int port, int value)
|
||||
{
|
||||
u_char al = value;
|
||||
|
||||
if (__builtin_constant_p(port) &&
|
||||
(((port) & 0xffff) < 0x100) &&
|
||||
((port) < 0x10000)) {
|
||||
__asm __volatile("outb %0,%1" : : "a" (al), "id" ((u_short)(port)));
|
||||
} else {
|
||||
__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
|
||||
}
|
||||
}
|
||||
|
46
sys/boot/pc98/loader/newvers.sh
Normal file
46
sys/boot/pc98/loader/newvers.sh
Normal file
@ -0,0 +1,46 @@
|
||||
#!/bin/sh -
|
||||
#
|
||||
# $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $
|
||||
#
|
||||
# Copyright (c) 1984, 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. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by the University of
|
||||
# California, Berkeley and its contributors.
|
||||
# 4. Neither the name of the University nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
|
||||
|
||||
LC_TIME=C; export LC_TIME
|
||||
u=${USER-root} h=`hostname` t=`date`
|
||||
#r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '`
|
||||
r=`awk -F: ' /^[0-9]\.[0-9]+:/ { print $1; exit }' $1`
|
||||
|
||||
echo "char bootprog_name[] = \"FreeBSD/i386 ${2}\";" > vers.c
|
||||
echo "char bootprog_rev[] = \"${r}\";" >> vers.c
|
||||
echo "char bootprog_date[] = \"${t}\";" >> vers.c
|
||||
echo "char bootprog_maker[] = \"${u}@${h}\";" >> vers.c
|
8
sys/boot/pc98/loader/version
Normal file
8
sys/boot/pc98/loader/version
Normal file
@ -0,0 +1,8 @@
|
||||
$Id: version,v 1.2 1998/09/17 23:52:16 msmith Exp $
|
||||
|
||||
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
|
||||
file is important. Make sure the current version number is on line 6.
|
||||
|
||||
0.2: Initial integration with BTX
|
||||
0.1: Initial i386 version, inspiration and some structure from the
|
||||
NetBSD version.
|
Loading…
x
Reference in New Issue
Block a user