makefs: make the buffer functions look exactly like the kernel ones
From NetBSD christos Sat Jan 26 00:19:39 2013 +0000 make the buffer functions look exactly like the kernel ones and add other cruft to make the kernel files compile. ffs.c 1.54 ffs/buf.c 1.13 ffs/buf.h 1.3 ffs/ffs_alloc.c 1.21 ffs/ffs_balloc.c 1.15 Reviewed by: marcel, ngie Obtained from: NetBSD Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D8404
This commit is contained in:
parent
9fc7a59f2a
commit
78b11a5903
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=313575
5
sys/boot/pc98/Makefile
Normal file
5
sys/boot/pc98/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= boot0 boot0.5 pc98boot btx boot2 cdboot kgzldr libpc98 loader
|
||||
|
||||
.include <bsd.subdir.mk>
|
29
sys/boot/pc98/Makefile.inc
Normal file
29
sys/boot/pc98/Makefile.inc
Normal file
@ -0,0 +1,29 @@
|
||||
# Common defines for all of /sys/boot/pc98/
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
BINDIR?= /boot
|
||||
|
||||
LOADER_ADDRESS?=0x200000
|
||||
CFLAGS+= -march=i386 -ffreestanding
|
||||
CFLAGS.gcc+= -mpreferred-stack-boundary=2
|
||||
CFLAGS+= ${CFLAGS_NO_SIMD} -msoft-float
|
||||
CFLAGS+= -Os -DPC98
|
||||
LDFLAGS+= -nostdlib
|
||||
|
||||
# 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
|
||||
|
||||
# compact binary with no padding between text, data, bss
|
||||
LDSCRIPT= ${SRCTOP}/sys/boot/i386/boot.ldscript
|
||||
LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary
|
||||
LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections
|
||||
|
||||
.include "../Makefile.inc"
|
26
sys/boot/pc98/boot0.5/Makefile
Normal file
26
sys/boot/pc98/boot0.5/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ${BOOT}.out
|
||||
INTERNALPROG=
|
||||
FILES= ${BOOT}
|
||||
MAN=
|
||||
SRCS= start.s boot.s boot0.5.s disk.s selector.s support.s syscons.s \
|
||||
putssjis.s
|
||||
CLEANFILES= ${BOOT} ${BOOT}.bin
|
||||
|
||||
BOOT= boot0.5
|
||||
|
||||
# The base address that we the boot0 code to to run it. Don't change this
|
||||
# unless you are glutton for punishment.
|
||||
BOOT_BOOT0_ORG?= 0x0000
|
||||
|
||||
LDFLAGS=-e start -Ttext ${BOOT_BOOT0_ORG} -Wl,-N,-T,${.CURDIR}/ldscript
|
||||
|
||||
# The size of boot0.5 must be 7168 bytes
|
||||
${BOOT}: ${BOOT}.bin
|
||||
cat ${BOOT}.bin /dev/zero | ${DD} of=${BOOT} bs=1 count=7168
|
||||
|
||||
${BOOT}.bin: ${BOOT}.out
|
||||
${OBJCOPY} -S -O binary ${BOOT}.out ${.TARGET}
|
||||
|
||||
.include <bsd.prog.mk>
|
174
sys/boot/pc98/boot0.5/boot.s
Normal file
174
sys/boot/pc98/boot0.5/boot.s
Normal file
@ -0,0 +1,174 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
.code16
|
||||
|
||||
.text
|
||||
.global boot
|
||||
#
|
||||
# Read bootstrap program and jump to it.
|
||||
#
|
||||
boot:
|
||||
# Step 1: Save parameters
|
||||
movw curdevice, %si
|
||||
movb daua(%si), %al
|
||||
movb %al, b_daua
|
||||
shlw %si
|
||||
movw secsize(%si), %ax
|
||||
movw %ax, b_secsize
|
||||
|
||||
movw curpartition, %si
|
||||
movb partnum(%si), %al # %al = real partition number
|
||||
xorb %ah, %ah
|
||||
movw %ax, b_partn # save real parttion number
|
||||
movb $5, %cl
|
||||
shlw %cl, %si # %si = offset to parttable
|
||||
addw $4, %si
|
||||
movb parttable(%si), %al # IPLS
|
||||
movb %al, b_sector
|
||||
incw %si
|
||||
movb parttable(%si), %al # IPLH
|
||||
movb %al, b_head
|
||||
incw %si # IPLC
|
||||
movw parttable(%si), %ax
|
||||
movw %ax, b_cylinder
|
||||
|
||||
# Step 2: Calculate the segment address of the bootstrap routine
|
||||
movw $0x1d00, %ax
|
||||
movw b_secsize, %cx
|
||||
shrw %cx
|
||||
shrw %cx
|
||||
subw %cx, %ax
|
||||
subw $0x100, %ax
|
||||
movw %ax, b_bootseg
|
||||
|
||||
# Step 3: Read bootstrap code
|
||||
movb $6, %ah
|
||||
movb b_daua, %al
|
||||
movw b_secsize, %bx
|
||||
shlw %bx # 2 sectors
|
||||
movw b_cylinder, %cx
|
||||
movb b_head, %dh
|
||||
movb b_sector, %dl
|
||||
movw b_bootseg, %es
|
||||
xorw %bp, %bp
|
||||
int $0x1b
|
||||
jc boot_error
|
||||
|
||||
# Step 4: Set DA/UA into BIOS work area
|
||||
xorw %ax, %ax
|
||||
movw %ax, %es
|
||||
movw $0x584, %bx # DISK_BOOT
|
||||
movb b_daua, %dl
|
||||
call write_biosparam
|
||||
|
||||
call sc_clean
|
||||
# Step 5: Set registers
|
||||
# %ah: 00
|
||||
# %al: DA/UA
|
||||
# %bx: Sector size * 2
|
||||
# %cx: cylinder number of boot partition
|
||||
# %si: pointer to partition table
|
||||
movw b_partn, %ax
|
||||
movb $5, %cl
|
||||
shl %cl, %ax # %ax = partition number * 32
|
||||
addw b_secsize, %ax
|
||||
movw %ax, %si # %si = pointer to partition table
|
||||
movw b_cylinder, %cx # %cx = cylinder
|
||||
movb b_head, %dh # %dh = head
|
||||
movb b_sector, %dl # %dl = sector
|
||||
movw b_bootseg, %es # %es = boot segment
|
||||
movb b_daua, %al # %al = DA/UA
|
||||
movw b_secsize, %bx
|
||||
shlw %bx # %bx = sector size * 2
|
||||
cli
|
||||
movw %cs:iniss, %ss # Restore stack pointer
|
||||
movw %cs:inisp, %sp
|
||||
push %es # Boot segment
|
||||
xorw %bp, %bp
|
||||
push %bp # 0
|
||||
movw %ax, %di # Save %ax
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds # %ds = 0
|
||||
movw %di, %ax # Restore %ax
|
||||
xorb %ah, %ah # %ah = 0
|
||||
xorw %di, %di # %di = 0
|
||||
sti
|
||||
|
||||
# Jump to bootstrap code
|
||||
lret
|
||||
# NOTREACHED
|
||||
|
||||
boot_error:
|
||||
ret
|
||||
|
||||
#
|
||||
# Try to boot from default partition.
|
||||
#
|
||||
.global trydefault
|
||||
trydefault:
|
||||
movw ndevice, %cx
|
||||
xorw %si, %si
|
||||
trydefault_loop:
|
||||
movw %si, curdevice
|
||||
push %cx
|
||||
push %si
|
||||
call read_ipl
|
||||
pop %si
|
||||
pop %cx
|
||||
cmpb $0x80, defpartflag
|
||||
jne nodefpart
|
||||
# Default partition is defined.
|
||||
push %cx
|
||||
movw npartition, %cx
|
||||
srch_part:
|
||||
movw %cx, %bx
|
||||
decw %bx
|
||||
movb defpartnum, %al # %al = real partition number
|
||||
cmpb partnum(%bx), %al
|
||||
jne not_match
|
||||
movw %bx, curpartition # Store partition number
|
||||
call boot
|
||||
not_match:
|
||||
loop srch_part
|
||||
pop %cx
|
||||
nodefpart:
|
||||
incw %si
|
||||
loop trydefault_loop
|
||||
ret
|
||||
|
||||
.data
|
||||
b_daua: .byte 0 # DA/UA
|
||||
b_head: .byte 0 # SYSH
|
||||
b_sector: .byte 0 # SYSS
|
||||
b_cylinder: .word 0 # SYSC
|
||||
b_bootseg: .word 0
|
||||
b_secsize: .word 0
|
||||
b_partn: .word 0 # Real partition number
|
293
sys/boot/pc98/boot0.5/boot0.5.s
Normal file
293
sys/boot/pc98/boot0.5/boot0.5.s
Normal file
@ -0,0 +1,293 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000, 2007.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
.global main
|
||||
.code16
|
||||
|
||||
.text
|
||||
main:
|
||||
# Check hireso mode
|
||||
movw $0x501, %bx # BIOS_FLAG
|
||||
call read_biosparam
|
||||
testb $0x08, %dl
|
||||
jz normalmode
|
||||
movb $1, ishireso
|
||||
normalmode:
|
||||
call sc_init
|
||||
|
||||
# Display title and copyright.
|
||||
movw $title, %di
|
||||
call sc_puts
|
||||
xorw %cx, %cx
|
||||
movw $1, %dx
|
||||
call sc_goto
|
||||
movw $copyright, %di
|
||||
call sc_puts
|
||||
|
||||
# Scan hard drives
|
||||
xorw %si, %si # number of partition
|
||||
call scan_sasi # SASI/IDE
|
||||
call scan_scsi # SCSI
|
||||
movw %si, ndevice
|
||||
orw %si, %si
|
||||
jnz drives_found
|
||||
jmp exit # No hard drives
|
||||
|
||||
drives_found:
|
||||
# Setup sector size dependent parameters
|
||||
movw %si, %cx # %cx = number of devices
|
||||
setup_loop:
|
||||
movw %cx, %di
|
||||
decw %di
|
||||
shlw %di
|
||||
movw secsize(%di), %ax
|
||||
cmpw $1024, %ax
|
||||
je setup_1024
|
||||
cmpw $512, %ax
|
||||
je setup_512
|
||||
# 256 bytes/sector
|
||||
movw $0x100, partoff(%di)
|
||||
movw $0x0fa, defflagoff(%di)
|
||||
movw $0x0fb, defpartoff(%di)
|
||||
movw $8, maxpart(%di)
|
||||
jmp setup_secsize_end
|
||||
# 1024 bytes/sector
|
||||
setup_1024:
|
||||
# XXX Fix me!
|
||||
movw $0x400, partoff(%di)
|
||||
movw $0x3fa, defflagoff(%di)
|
||||
movw $0x3fb, defpartoff(%di)
|
||||
movb $32, maxpart(%di)
|
||||
jmp setup_secsize_end
|
||||
# 512 bytes/sector
|
||||
setup_512:
|
||||
movw $0x200, partoff(%di)
|
||||
movw $0x1fa, defflagoff(%di)
|
||||
movw $0x1fb, defpartoff(%di)
|
||||
movb $16, maxpart(%di)
|
||||
setup_secsize_end:
|
||||
loop setup_loop
|
||||
|
||||
# For debug with floppy, fake the parameter.
|
||||
movw $0x584, %bx # DISK_BOOT
|
||||
call read_biosparam
|
||||
andb $0xf0, %dl
|
||||
cmpb $0x90, %ah
|
||||
jne boot_from_hdd
|
||||
movb daua, %dl
|
||||
call write_biosparam
|
||||
|
||||
boot_from_hdd:
|
||||
movw $500, %cx
|
||||
wait_0_5:
|
||||
call wait1ms
|
||||
loop wait_0_5
|
||||
|
||||
# If the TAB is pressed, don't try to boot from default partition
|
||||
xorw %di, %di # flag
|
||||
wait_key_release:
|
||||
call sc_iskeypress
|
||||
orw %ax, %ax
|
||||
jz key_release # KBD buffer empty.
|
||||
call sc_getc
|
||||
cmpb $0x0f, %ah # TAB
|
||||
jne wait_key_release
|
||||
# TAB pressed
|
||||
movw $1, %di
|
||||
jmp wait_key_release
|
||||
key_release:
|
||||
orw %di, %di
|
||||
jnz dont_try_default # TAB pressed.
|
||||
call trydefault
|
||||
# Default partition not found.
|
||||
dont_try_default:
|
||||
call show_usage
|
||||
call showdevices
|
||||
call selector
|
||||
exit:
|
||||
ret
|
||||
#
|
||||
# Display usage
|
||||
#
|
||||
show_usage:
|
||||
movw $44, %cx
|
||||
movw $3, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage1, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $4, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage2, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $5, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage3, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $7, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage4, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $8, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage5, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $9, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage6, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $10, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage7, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $11, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage8, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $16, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage9, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $17, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage10, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $18, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage11, %di
|
||||
call sc_puts
|
||||
movw $44, %cx
|
||||
movw $19, %dx
|
||||
call sc_goto
|
||||
movw $msg_usage12, %di
|
||||
call sc_puts
|
||||
ret
|
||||
|
||||
#
|
||||
# Display device list
|
||||
#
|
||||
showdevices:
|
||||
movw $2, %cx
|
||||
movw $4, %dx
|
||||
call sc_goto
|
||||
movw $msg_device, %di
|
||||
call sc_puts
|
||||
xorw %si, %si # %si = device number
|
||||
movw ndevice, %cx # %cx = number of devices
|
||||
showdev_loop:
|
||||
push %cx
|
||||
movw $2, %cx
|
||||
movw $5, %dx
|
||||
addw %si, %dx
|
||||
call sc_goto
|
||||
# Check DA
|
||||
movb daua(%si), %al
|
||||
push %ax
|
||||
andb $0xf0, %al
|
||||
cmpb $0x80, %al
|
||||
je show_sasi
|
||||
cmpb $0xa0, %al
|
||||
je show_scsi
|
||||
# unknown device
|
||||
movw $msg_unknown, %di
|
||||
call sc_puts
|
||||
jmp showunit
|
||||
# SASI
|
||||
show_sasi:
|
||||
movw $msg_sasi, %di
|
||||
call sc_puts
|
||||
jmp showunit
|
||||
# SCSI
|
||||
show_scsi:
|
||||
movw $msg_scsi, %di
|
||||
call sc_puts
|
||||
# Display unit number.
|
||||
showunit:
|
||||
pop %ax
|
||||
andb $0x0f, %al
|
||||
addb $'0', %al
|
||||
call sc_putc
|
||||
incw %si
|
||||
pop %cx
|
||||
loop showdev_loop
|
||||
movw ndevice, %dx
|
||||
addw $5, %dx
|
||||
movw $2, %cx
|
||||
call sc_goto
|
||||
movw $msg_exitmenu, %di
|
||||
call sc_puts
|
||||
ret
|
||||
|
||||
.data
|
||||
.global curdevice, ndevice
|
||||
ndevice: .word 0 # number of device
|
||||
curdevice: .word 0 # current device
|
||||
|
||||
.global ishireso
|
||||
ishireso: .byte 0
|
||||
|
||||
title: .asciz "PC98 Boot Selector Version 1.2"
|
||||
copyright: .ascii "(C)Copyright 1999-2007 KATO Takenori. "
|
||||
.asciz "All rights reserved."
|
||||
msg_device: .asciz "Device"
|
||||
msg_sasi: .asciz "SASI/IDE unit "
|
||||
msg_scsi: .asciz "SCSI ID "
|
||||
msg_unknown: .asciz "unknown unit "
|
||||
msg_exitmenu: .asciz "Exit this menu"
|
||||
msg_usage1: .asciz "Device list"
|
||||
msg_usage2: .asciz "UP, DOWN: select boot device"
|
||||
msg_usage3: .asciz "RETURN: move to slice list"
|
||||
msg_usage4: .asciz "Slice list"
|
||||
msg_usage5: .asciz "UP, DOWN: select boot slice"
|
||||
msg_usage6: .asciz "RETURN: boot"
|
||||
msg_usage7: .asciz "SPACE: toggle default"
|
||||
msg_usage8: .asciz "ESC: move to device list"
|
||||
msg_usage9: .asciz "LEGEND"
|
||||
msg_usage10: .asciz ">>: selected device/slice"
|
||||
msg_usage11: .asciz "*: default slice to boot"
|
||||
msg_usage12: .asciz "!: unbootable slice"
|
||||
|
||||
.bss
|
||||
.global daua, secsize, defflagoff, defpartoff
|
||||
.global maxpart, partoff
|
||||
daua: .space 12 # DA/DU list
|
||||
secsize: .space 12 * 2 # Sector soize
|
||||
defflagoff: .space 12 * 2
|
||||
defpartoff: .space 12 * 2
|
||||
maxpart: .space 12 * 2
|
||||
partoff: .space 12 * 2
|
296
sys/boot/pc98/boot0.5/disk.s
Normal file
296
sys/boot/pc98/boot0.5/disk.s
Normal file
@ -0,0 +1,296 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
.code16
|
||||
.text
|
||||
#
|
||||
# Check magic number at the end of the sector 0
|
||||
#
|
||||
check_magic:
|
||||
movw curdevice, %si
|
||||
shlw %si
|
||||
movw secsize(%si), %bx
|
||||
decw %bx
|
||||
decw %bx
|
||||
movw iplbuf(%bx), %ax
|
||||
cmpw $0xaa55, %ax
|
||||
je magic_ok
|
||||
movw $1, %ax
|
||||
ret
|
||||
magic_ok:
|
||||
xorw %ax, %ax
|
||||
ret
|
||||
|
||||
#
|
||||
# Copy partition table from buffer to parttable.
|
||||
#
|
||||
setup_partition:
|
||||
push %cs
|
||||
pop %es
|
||||
movw curdevice, %bx
|
||||
shlw %bx
|
||||
movw maxpart(%bx), %cx # %cx = max num of partitions
|
||||
movw partoff(%bx), %di
|
||||
movw %di, %bx # %bx = offset to partition table
|
||||
xorw %dx, %dx # %dx = partition number
|
||||
setup_partition_loop:
|
||||
push %cx
|
||||
movw %dx, %si
|
||||
movb $5, %cl
|
||||
shlw %cl, %si
|
||||
addw %bx, %si
|
||||
movb iplbuf(%si), %al
|
||||
orb %al, %al
|
||||
jz unused_partition
|
||||
addw $iplbuf, %si
|
||||
movw npartition, %ax
|
||||
movw %ax, %di
|
||||
movb $5, %cl
|
||||
shlw %cl, %di
|
||||
addw $parttable, %di
|
||||
movw $32, %cx
|
||||
rep
|
||||
movsb
|
||||
movw %ax, %di
|
||||
addw $partnum, %di
|
||||
movb %dl, (%di)
|
||||
incw npartition
|
||||
unused_partition:
|
||||
incw %dx
|
||||
pop %cx
|
||||
loop setup_partition_loop
|
||||
ret
|
||||
|
||||
#
|
||||
# Read IPL and partition table in the current device.
|
||||
#
|
||||
.global read_ipl
|
||||
read_ipl:
|
||||
movw curdevice, %ax
|
||||
movw %ax, %si # %si = device number
|
||||
movw %ax, %di
|
||||
shlw %di
|
||||
|
||||
movw %cs, %ax
|
||||
movw %ax, %es
|
||||
movb $6, %ah
|
||||
movb daua(%si), %al
|
||||
movw $0x400, %bx
|
||||
xorw %cx, %cx
|
||||
xorw %dx, %dx
|
||||
movw $iplbuf, %bp
|
||||
int $0x1b
|
||||
jc read_ipl_error
|
||||
movw defflagoff(%di), %bx
|
||||
movb iplbuf(%bx), %al
|
||||
movb %al, defpartflag
|
||||
incw %bx
|
||||
movb iplbuf(%bx), %al
|
||||
movb %al, defpartnum
|
||||
movw $0, npartition
|
||||
call check_magic
|
||||
orw %ax, %ax
|
||||
jnz no_magic
|
||||
call setup_partition
|
||||
no_magic:
|
||||
xorw %ax, %ax
|
||||
read_ipl_error:
|
||||
xorw %bx, %bx
|
||||
movw %bx, %es
|
||||
ret
|
||||
|
||||
#
|
||||
# Restore IPL from the buffer
|
||||
#
|
||||
.global write_ipl
|
||||
write_ipl:
|
||||
movw curdevice, %ax
|
||||
movw %ax, %si
|
||||
movw %ax, %di
|
||||
shlw %di
|
||||
|
||||
# Restore default boot partition info.
|
||||
movw defflagoff(%di), %bx
|
||||
movb defpartflag, %al
|
||||
movb %al, iplbuf(%bx)
|
||||
incw %bx
|
||||
movb defpartnum, %al
|
||||
movb %al, iplbuf(%bx)
|
||||
|
||||
movw %cs, %ax
|
||||
movw %ax, %es
|
||||
movb $5, %ah
|
||||
movb daua(%si), %al
|
||||
movw secsize(%di), %bx
|
||||
xorw %cx, %cx
|
||||
xorw %dx, %dx
|
||||
movw $iplbuf, %bp
|
||||
int $0x1b
|
||||
jc write_ipl_error
|
||||
xorw %ax, %ax
|
||||
write_ipl_error:
|
||||
xorw %bx, %bx
|
||||
movw %bx, %es
|
||||
ret
|
||||
|
||||
#
|
||||
# Scan HDD devices
|
||||
#
|
||||
.global scan_sasi, scan_scsi
|
||||
# Scan SASI disk
|
||||
scan_sasi:
|
||||
# SASI Disk
|
||||
movw $4, %cx
|
||||
movw $0x0001, %ax # %ah = unit number, %al = for bit operation
|
||||
|
||||
sasi_loop:
|
||||
movw %si, %di
|
||||
shlw %di
|
||||
movw $0x55d, %bx # DISK_EQUIP
|
||||
call read_biosparam
|
||||
testb %al, %dl
|
||||
jz no_sasi_unit
|
||||
movb $0x80, %dh
|
||||
addb %ah, %dh # %dh = DA/UA
|
||||
movb %dh, daua(%si) # Store DA/UA
|
||||
|
||||
# Try new sense command
|
||||
push %ax
|
||||
push %cx
|
||||
movb %dh, %al
|
||||
movb $0x84, %ah
|
||||
int $0x1b
|
||||
pop %cx
|
||||
pop %ax
|
||||
jc err_newsense
|
||||
movw %bx, %dx
|
||||
jmp found_sasi_unit
|
||||
|
||||
err_newsense:
|
||||
movw $0x457, %bx # capacity & sector size of IDE HDD
|
||||
call read_biosparam
|
||||
orb %ah, %ah
|
||||
jz sasi_1
|
||||
cmpb $1, %ah
|
||||
jz sasi_2
|
||||
|
||||
# SASI #3/#4
|
||||
movw $512, %dx # XXX
|
||||
jmp found_sasi_unit
|
||||
|
||||
sasi_1:
|
||||
# SASI #1
|
||||
testb $0x80, %dl
|
||||
jz sasi_256
|
||||
jmp sasi_512
|
||||
sasi_2:
|
||||
# SASI #2
|
||||
testb $0x40, %dl
|
||||
jz sasi_256
|
||||
jmp sasi_512
|
||||
|
||||
sasi_256:
|
||||
movw $256, %dx
|
||||
jmp found_sasi_unit
|
||||
sasi_512:
|
||||
movw $512, %dx
|
||||
found_sasi_unit:
|
||||
movw %dx, secsize(%di)
|
||||
incw %si
|
||||
no_sasi_unit:
|
||||
incb %ah
|
||||
shlb %al
|
||||
loop sasi_loop
|
||||
ret
|
||||
|
||||
#
|
||||
# Scan SCSI disk
|
||||
# SI number of disks
|
||||
# destroyed: %ax, %bx, %cx, %dx
|
||||
scan_scsi:
|
||||
movw $8, %cx
|
||||
movw $0x0001, %ax # %ah = ID number, %al = for bit operation
|
||||
scsi_loop:
|
||||
# Check whether drive exist.
|
||||
movw %si, %di
|
||||
shlw %di
|
||||
movw $0x482, %bx # DISK_EQUIPS
|
||||
call read_biosparam
|
||||
testb %al, %dl
|
||||
jz no_scsi_unit
|
||||
xorw %bx, %bx
|
||||
movb %ah, %bl
|
||||
shlw %bx
|
||||
shlw %bx
|
||||
addw $0x460, %bx # SCSI parameter block
|
||||
call read_biosparam
|
||||
orb %dl, %dl
|
||||
jz no_scsi_unit
|
||||
|
||||
# SCSI harddrive found.
|
||||
movb $0xa0, %dh
|
||||
addb %ah, %dh
|
||||
movb %dh, daua(%si)
|
||||
|
||||
# Check sector size.
|
||||
addw $3, %bx
|
||||
call read_biosparam
|
||||
andb $0x30, %dl
|
||||
cmpb $0x20, %dl
|
||||
je scsi_1024
|
||||
cmpb $0x10, %dl
|
||||
je scsi_512
|
||||
movw $256, %dx
|
||||
jmp found_scsi
|
||||
scsi_1024:
|
||||
movw $1024, %dx
|
||||
jmp found_scsi
|
||||
scsi_512:
|
||||
movw $512, %dx
|
||||
found_scsi:
|
||||
movw %dx, secsize(%di)
|
||||
incw %si
|
||||
no_scsi_unit:
|
||||
incb %ah
|
||||
shlb %al
|
||||
loop scsi_loop
|
||||
ret
|
||||
|
||||
.data
|
||||
.global defpartflag, defpartnum, npartition
|
||||
defpartflag: .byte 0
|
||||
defpartnum: .byte 0
|
||||
npartition: .word 0 # number of partitions
|
||||
|
||||
.bss
|
||||
.global partnum, parttable
|
||||
iplbuf: .space 0x400 # Read buffer for IPL
|
||||
partnum: .space 32 # Index of parttable
|
||||
parttable: .space 1024 # Copy of valid partition table
|
12
sys/boot/pc98/boot0.5/ldscript
Normal file
12
sys/boot/pc98/boot0.5/ldscript
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) }
|
||||
. = 0x1243;
|
||||
.putssjis : { *(.putssjis) }
|
||||
.bss : { *(.bss) }
|
||||
}
|
137
sys/boot/pc98/boot0.5/putssjis.s
Normal file
137
sys/boot/pc98/boot0.5/putssjis.s
Normal file
@ -0,0 +1,137 @@
|
||||
# Copyright (c) KATO Takenori, 2007.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
.code16
|
||||
.section .putssjis, "awx", @progbits
|
||||
|
||||
#
|
||||
# Display string with Shift-JIS support
|
||||
# %si: address of string, %di: T-VRAM address, %cx: count
|
||||
#
|
||||
|
||||
# Absolute address of putssjis_entry must be 0x1243.
|
||||
putssjis_entry:
|
||||
push %es
|
||||
push %ax
|
||||
# Setup the T-VRAM segement address.
|
||||
xorw %ax, %ax
|
||||
movw %ax, %es
|
||||
movw $0xa000, %ax
|
||||
testb $0x08, %es:0x501
|
||||
jz normalmode
|
||||
movw $0xe000, %ax
|
||||
normalmode:
|
||||
movw %ax, %es
|
||||
|
||||
putssjis_loop:
|
||||
lodsw
|
||||
call check_sjis
|
||||
jc put_2byte_char
|
||||
|
||||
# 1 byte character
|
||||
xorb %ah, %ah
|
||||
testb $0xe0, %al # Check control code.
|
||||
jnz put_1byte_char
|
||||
movb $0x20, %al # Convert control code into the space.
|
||||
put_1byte_char:
|
||||
stosw
|
||||
decw %si
|
||||
jmp putssjis_loop_end
|
||||
|
||||
put_2byte_char:
|
||||
subb $0x20, %al
|
||||
|
||||
# Check 2byte "hankaku"
|
||||
cmp $0x09, %al
|
||||
je put_2byte_hankaku
|
||||
cmp $0x0a, %al
|
||||
je put_2byte_hankaku
|
||||
cmp $0x0b, %al
|
||||
je put_2byte_hankaku
|
||||
jmp put_2byte_zenkaku
|
||||
|
||||
put_2byte_hankaku:
|
||||
stosw
|
||||
jmp putssjis_loop_end
|
||||
|
||||
put_2byte_zenkaku:
|
||||
stosw
|
||||
orb $0x80, %ah
|
||||
stosw
|
||||
decw %cx
|
||||
|
||||
putssjis_loop_end:
|
||||
loop putssjis_loop
|
||||
|
||||
pop %ax
|
||||
pop %es
|
||||
ret
|
||||
|
||||
# Check 2-byte code.
|
||||
check_sjis:
|
||||
cmpb $0x80, %al
|
||||
jbe found_ank_kana
|
||||
cmpb $0xa0, %al
|
||||
jb found_2byte_char
|
||||
cmpb $0xe0, %al
|
||||
jb found_ank_kana
|
||||
cmpb $0xf0, %al
|
||||
jae found_ank_kana
|
||||
jmp found_2byte_char
|
||||
found_ank_kana:
|
||||
clc
|
||||
ret
|
||||
|
||||
found_2byte_char:
|
||||
# Convert Shift-JIS into JIS.
|
||||
cmpb $0x9f, %al
|
||||
ja sjis_h_2 # Upper > 0x9f
|
||||
subb $0x71, %al # Upper -= 0x71
|
||||
jmp sjis_lower
|
||||
sjis_h_2:
|
||||
subb $0xb1, %al # Upper -= 0xb1
|
||||
sjis_lower:
|
||||
salb %al # Upper *= 2
|
||||
incb %al # Upper += 1
|
||||
|
||||
cmpb $0x7f, %ah
|
||||
jbe sjis_l_2
|
||||
decb %ah # Lower -= 1 if lower > 0x7f
|
||||
sjis_l_2:
|
||||
cmpb $0x9e, %ah
|
||||
jb sjis_l_3
|
||||
subb $0x7d, %ah # Lower -= 0x7d
|
||||
incb %al # Upper += 1
|
||||
jmp check_2byte_end
|
||||
sjis_l_3:
|
||||
subb $0x1f, %ah # Lower -= 0x1f
|
||||
check_2byte_end:
|
||||
stc
|
||||
ret
|
450
sys/boot/pc98/boot0.5/selector.s
Normal file
450
sys/boot/pc98/boot0.5/selector.s
Normal file
@ -0,0 +1,450 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000, 2007.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
.code16
|
||||
|
||||
.text
|
||||
#
|
||||
# Display partition table.
|
||||
#
|
||||
showpartitions:
|
||||
# Clear partition table area
|
||||
movw $16, %cx
|
||||
clear_part:
|
||||
push %cx
|
||||
movw %cx, %dx
|
||||
decw %dx
|
||||
addw $5, %dx
|
||||
movw $20, %cx
|
||||
call sc_goto
|
||||
movw $msg_spc, %di
|
||||
call sc_puts
|
||||
pop %cx
|
||||
loop clear_part
|
||||
|
||||
# Check `Exit' menu
|
||||
movw curdevice, %ax
|
||||
cmpw ndevice, %ax
|
||||
je no_slice
|
||||
|
||||
# XXX Move this to a suitable place!
|
||||
movw $22, %cx
|
||||
movw $4, %dx
|
||||
call sc_goto
|
||||
movw $msg_slice, %di
|
||||
call sc_puts
|
||||
|
||||
# Check the number of partitions
|
||||
movw npartition, %cx
|
||||
orw %cx, %cx
|
||||
jnz partitionexist
|
||||
no_slice:
|
||||
# Just show the `no slice' message.
|
||||
movw $22, %cx
|
||||
movw $5, %dx
|
||||
call sc_goto
|
||||
movw $msg_noslice, %di
|
||||
call sc_puts
|
||||
ret
|
||||
partitionexist:
|
||||
xorw %si, %si # %si = partition number
|
||||
showpart_loop:
|
||||
push %cx # %cx = number of partitions
|
||||
movw $22, %cx
|
||||
movw %si, %dx
|
||||
addw $5, %dx
|
||||
call sc_goto
|
||||
movw %si, %di
|
||||
movb $5, %cl
|
||||
shlw %cl, %di
|
||||
addw $0x10, %di # SYSM field
|
||||
# SYSM: space filled string. Don't use sc_puts.
|
||||
movw $16, %cx
|
||||
showpart_name:
|
||||
push %cx
|
||||
movb parttable(%di), %al
|
||||
call sc_putc
|
||||
incw %di
|
||||
pop %cx
|
||||
loop showpart_name
|
||||
incw %si
|
||||
pop %cx
|
||||
loop showpart_loop
|
||||
ret
|
||||
|
||||
#
|
||||
# Show default slice indicator
|
||||
# If the default boot slice exists, `*' indicator will be showed.
|
||||
#
|
||||
showdefaultslicemark:
|
||||
cmpb $0x80, defpartflag
|
||||
je defpartexist
|
||||
ret
|
||||
defpartexist:
|
||||
movw npartition, %cx
|
||||
defslice_loop:
|
||||
movw %cx, %bx
|
||||
decw %bx
|
||||
push %cx
|
||||
push %bx
|
||||
movw $40, %cx
|
||||
movw %bx, %dx
|
||||
addw $5, %dx
|
||||
call sc_goto
|
||||
|
||||
pop %bx
|
||||
pop %cx
|
||||
movb defpartnum, %al
|
||||
cmpb partnum(%bx), %al
|
||||
jne nomatch
|
||||
movb $'*', %al
|
||||
call sc_putc
|
||||
jmp defslice_done
|
||||
nomatch:
|
||||
movb $' ', %al
|
||||
call sc_putc
|
||||
defslice_done:
|
||||
loop defslice_loop
|
||||
ret
|
||||
|
||||
#
|
||||
# Hide default slice indicator
|
||||
#
|
||||
hidedefaultslicemark:
|
||||
movw $16, %cx
|
||||
hidedefslice_loop:
|
||||
push %cx
|
||||
movw %cx, %dx
|
||||
addw $4, %dx
|
||||
movw $40, %cx
|
||||
call sc_goto
|
||||
movb $' ', %al
|
||||
call sc_putc
|
||||
pop %cx
|
||||
loop hidedefslice_loop
|
||||
ret
|
||||
|
||||
#
|
||||
# Toggle default slice
|
||||
#
|
||||
toggle_default:
|
||||
cmpb $0x80, defpartflag
|
||||
jne set_default
|
||||
# Clear default
|
||||
movb $0, defpartflag
|
||||
call write_ipl # Restore
|
||||
call hidedefaultslicemark
|
||||
ret
|
||||
# Set default slice
|
||||
set_default:
|
||||
movw curpartition, %si
|
||||
movb partnum(%si), %al # %al = real partition number
|
||||
movb $5, %cl
|
||||
shlw %cl, %si
|
||||
# Default slice must be bootable
|
||||
testb $0x80, parttable(%si)
|
||||
jnz curpart_bootable
|
||||
# Current partition is not bootable.
|
||||
ret
|
||||
curpart_bootable:
|
||||
movb $0x80, defpartflag
|
||||
movb %al, defpartnum
|
||||
call write_ipl # Restore
|
||||
call showdefaultslicemark
|
||||
ret
|
||||
|
||||
#
|
||||
# Show/hide cursor
|
||||
#
|
||||
show_devcurs:
|
||||
xorw %cx, %cx
|
||||
movw curdevice, %dx
|
||||
addw $5, %dx
|
||||
call sc_goto
|
||||
movb $'>', %al
|
||||
call sc_putc
|
||||
movb $'>', %al
|
||||
call sc_putc
|
||||
ret
|
||||
|
||||
hide_devcurs:
|
||||
xorw %cx, %cx
|
||||
movw curdevice, %dx
|
||||
addw $5, %dx
|
||||
call sc_goto
|
||||
movb $' ', %al
|
||||
call sc_putc
|
||||
movb $' ', %al
|
||||
call sc_putc
|
||||
ret
|
||||
|
||||
show_slicecurs:
|
||||
movw $20, %cx
|
||||
movw curpartition, %dx
|
||||
addw $5, %dx
|
||||
call sc_goto
|
||||
movb $'>', %al
|
||||
call sc_putc
|
||||
movb $'>', %al
|
||||
call sc_putc
|
||||
ret
|
||||
|
||||
hide_slicecurs:
|
||||
movw $20, %cx
|
||||
movw curpartition, %dx
|
||||
addw $5, %dx
|
||||
call sc_goto
|
||||
movb $' ', %al
|
||||
call sc_putc
|
||||
movb $' ', %al
|
||||
call sc_putc
|
||||
ret
|
||||
|
||||
isforceboot:
|
||||
xorw %cx, %cx
|
||||
movw $20, %dx
|
||||
call sc_goto
|
||||
movw $msg_force, %di
|
||||
call sc_puts
|
||||
call sc_getc
|
||||
push %ax
|
||||
xorw %cx, %cx
|
||||
movw $20, %dx
|
||||
call sc_goto
|
||||
movw $msg_forceclr, %di
|
||||
call sc_puts
|
||||
pop %ax
|
||||
cmpb $0x15, %ah
|
||||
je force_yes
|
||||
xorw %ax, %ax
|
||||
ret
|
||||
force_yes:
|
||||
movw $1, %ax
|
||||
ret
|
||||
|
||||
#
|
||||
# Main loop for device mode
|
||||
#
|
||||
devmode:
|
||||
call read_ipl
|
||||
call hidedefaultslicemark
|
||||
call showpartitions
|
||||
call showdefaultslicemark
|
||||
call show_devcurs
|
||||
|
||||
movw $2, %cx
|
||||
movw $4, %dx
|
||||
call sc_goto
|
||||
movb $0xe5, %al
|
||||
movw $6, %cx
|
||||
call sc_setattr
|
||||
movw $22, %cx
|
||||
movw $4, %dx
|
||||
call sc_goto
|
||||
movb $0xe1, %al
|
||||
movw $5, %cx
|
||||
call sc_setattr
|
||||
movw $44, %cx
|
||||
movw $3, %dx
|
||||
call sc_goto
|
||||
movb $0xe5, %al
|
||||
movw $11, %cx
|
||||
call sc_setattr
|
||||
movw $44, %cx
|
||||
movw $7, %dx
|
||||
call sc_goto
|
||||
movb $0xe1, %al
|
||||
movw $10, %cx
|
||||
call sc_setattr
|
||||
|
||||
devmode_loop:
|
||||
call sc_getc
|
||||
movw ndevice, %bx
|
||||
cmpb $0x3a, %ah # UP
|
||||
je dev_up
|
||||
cmpb $0x3d, %ah # DOWN
|
||||
je dev_down
|
||||
cmpb $0x3c, %ah # RIGHT
|
||||
je dev_right
|
||||
cmpb $0x1c, %ah # RETURN
|
||||
jne devmode_loop
|
||||
cmpw curdevice, %bx
|
||||
jne dev_right
|
||||
movw $3, mode # N88-BASIC
|
||||
ret
|
||||
|
||||
# XXX
|
||||
.space 5, 0x90
|
||||
ret # Dummy ret @0x9ab
|
||||
|
||||
dev_up:
|
||||
cmpw $0, curdevice
|
||||
je devmode_loop
|
||||
call hide_devcurs
|
||||
decw curdevice
|
||||
call read_ipl
|
||||
call hidedefaultslicemark
|
||||
call showpartitions
|
||||
call showdefaultslicemark
|
||||
call show_devcurs
|
||||
jmp devmode_loop
|
||||
dev_down:
|
||||
cmpw curdevice, %bx
|
||||
je devmode_loop
|
||||
call hide_devcurs
|
||||
incw curdevice
|
||||
call read_ipl
|
||||
call hidedefaultslicemark
|
||||
call showpartitions
|
||||
call showdefaultslicemark
|
||||
call show_devcurs
|
||||
jmp devmode_loop
|
||||
dev_right:
|
||||
cmpw curdevice, %bx
|
||||
je devmode_loop
|
||||
movw $1, mode # Slice mode
|
||||
ret
|
||||
|
||||
#
|
||||
# main loop for slice mode
|
||||
#
|
||||
slicemode:
|
||||
movw $0, curpartition
|
||||
call show_slicecurs
|
||||
movw $2, %cx
|
||||
movw $4, %dx
|
||||
call sc_goto
|
||||
movb $0xe1, %al
|
||||
movw $6, %cx
|
||||
call sc_setattr
|
||||
movw $22, %cx
|
||||
movw $4, %dx
|
||||
call sc_goto
|
||||
movb $0xe5, %al
|
||||
movw $5, %cx
|
||||
call sc_setattr
|
||||
movw $44, %cx
|
||||
movw $3, %dx
|
||||
call sc_goto
|
||||
movb $0xe1, %al
|
||||
movw $11, %cx
|
||||
call sc_setattr
|
||||
movw $44, %cx
|
||||
movw $7, %dx
|
||||
call sc_goto
|
||||
movb $0xe5, %al
|
||||
movw $10, %cx
|
||||
call sc_setattr
|
||||
|
||||
slicemode_loop:
|
||||
call sc_getc
|
||||
cmpb $0x3a, %ah # UP
|
||||
je slice_up
|
||||
cmpb $0x3d, %ah # DOWN
|
||||
je slice_down
|
||||
cmpb $0x3b, %ah # LEFT
|
||||
je slice_esc
|
||||
cmpb $0x00, %ah # ESC
|
||||
je slice_esc
|
||||
cmpb $0x1c, %ah # RETURN
|
||||
je slice_ret
|
||||
cmpb $0x34, %ah # SPC
|
||||
je slice_spc
|
||||
cmpb $0x62, %ah # f1
|
||||
je slice_spc
|
||||
jmp slicemode_loop
|
||||
slice_up:
|
||||
cmpw $0, curpartition
|
||||
je slicemode_loop
|
||||
call hide_slicecurs
|
||||
decw curpartition
|
||||
call show_slicecurs
|
||||
jmp slicemode_loop
|
||||
slice_down:
|
||||
movw curpartition, %bx
|
||||
movw npartition, %ax
|
||||
decw %ax
|
||||
cmpw %bx, %ax
|
||||
je slicemode_loop
|
||||
call hide_slicecurs
|
||||
incw curpartition
|
||||
call show_slicecurs
|
||||
jmp slicemode_loop
|
||||
slice_esc:
|
||||
movw $0, mode # Device mode
|
||||
ret
|
||||
slice_spc:
|
||||
call toggle_default
|
||||
jmp slicemode_loop
|
||||
slice_ret:
|
||||
# Test bit 7 of mid
|
||||
movw curpartition, %si
|
||||
movb $5, %cl
|
||||
shlw %cl, %si
|
||||
testb $0x80, parttable(%si)
|
||||
jnz bootable_slice
|
||||
call isforceboot
|
||||
orw %ax, %ax
|
||||
jz slicemode_loop
|
||||
bootable_slice:
|
||||
call boot
|
||||
jmp slicemode_loop
|
||||
|
||||
#
|
||||
# Main loop
|
||||
#
|
||||
.global selector
|
||||
selector:
|
||||
movw $0, curdevice # trydefault may change the curdevice.
|
||||
movw $0, mode
|
||||
|
||||
selector_loop:
|
||||
cmpw $0, mode
|
||||
je status_dev
|
||||
cmpw $1, mode
|
||||
je status_slice
|
||||
ret
|
||||
status_dev:
|
||||
call devmode
|
||||
jmp selector_loop
|
||||
status_slice:
|
||||
call slicemode
|
||||
jmp selector_loop
|
||||
|
||||
.data
|
||||
.global curpartition
|
||||
curpartition: .word 0 # current patition
|
||||
mode: .word 0
|
||||
|
||||
msg_spc: .asciz " "
|
||||
msg_slice: .asciz "Slice"
|
||||
msg_noslice: .asciz "no slice"
|
||||
msg_force: .asciz "This slice is not bootable. Continue? (Y / [N])"
|
||||
msg_forceclr: .asciz " "
|
73
sys/boot/pc98/boot0.5/start.s
Normal file
73
sys/boot/pc98/boot0.5/start.s
Normal file
@ -0,0 +1,73 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000, 2007.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
.global start
|
||||
.code16
|
||||
|
||||
.text
|
||||
start:
|
||||
jmp start1
|
||||
|
||||
# Magic
|
||||
.org 0x053, 0x20
|
||||
.byte 0x4e, 0x45, 0x43
|
||||
|
||||
.org 0x8f
|
||||
.byte 0x32, 0x2e, 0x37, 0x30
|
||||
|
||||
.org 0x2d4
|
||||
start1:
|
||||
# The instruction 'call 0x9ab' can be here. See also selector.s.
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
cli
|
||||
movw %cs, %ax
|
||||
movw %ax, %ds
|
||||
movw %ss, iniss
|
||||
movw %sp, inisp
|
||||
movw %ax, %ss
|
||||
movw $0xfffe, %sp
|
||||
sti
|
||||
xorw %ax, %ax
|
||||
movw %ax, %es
|
||||
call main
|
||||
|
||||
cli
|
||||
movw %cs:iniss, %ss
|
||||
movw %cs:inisp, %sp
|
||||
sti
|
||||
int $0x1e
|
||||
# NOTREACHED
|
||||
lret
|
||||
|
||||
.data
|
||||
.global iniss, inisp
|
||||
iniss: .word 0
|
||||
inisp: .word 0
|
94
sys/boot/pc98/boot0.5/support.s
Normal file
94
sys/boot/pc98/boot0.5/support.s
Normal file
@ -0,0 +1,94 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
.code16
|
||||
|
||||
.text
|
||||
#
|
||||
# Wait 1ms
|
||||
#
|
||||
.global wait1ms
|
||||
wait1ms:
|
||||
push %cx
|
||||
movw $800, %cx
|
||||
wait_loop:
|
||||
outb %al, $0x5f
|
||||
loop wait_loop
|
||||
pop %cx
|
||||
ret
|
||||
|
||||
#
|
||||
# Read one byte from BIOS parameter block
|
||||
# %bx offset
|
||||
# %dl value
|
||||
#
|
||||
.global read_biosparam
|
||||
read_biosparam:
|
||||
movb %es:(%bx), %dl
|
||||
ret
|
||||
|
||||
#
|
||||
# Write one byte to BIOS parameter block
|
||||
# %bx offset
|
||||
# %dl value
|
||||
#
|
||||
.global write_biosparam
|
||||
write_biosparam:
|
||||
movb %dl, %es:(%bx)
|
||||
ret
|
||||
|
||||
#
|
||||
# beep
|
||||
#
|
||||
.global beep_on, beep_off, beep
|
||||
beep_on:
|
||||
movb $0x17, %ah
|
||||
int $0x18
|
||||
ret
|
||||
|
||||
beep_off:
|
||||
movb $0x18, %ah
|
||||
int $0x18
|
||||
ret
|
||||
|
||||
beep:
|
||||
push %cx
|
||||
call beep_on
|
||||
movw $100, %cx
|
||||
beep_loop1:
|
||||
call wait1ms
|
||||
loop beep_loop1
|
||||
call beep_off
|
||||
movw $50, %cx
|
||||
beep_loop2:
|
||||
call wait1ms
|
||||
loop beep_loop2
|
||||
pop %cx
|
||||
ret
|
253
sys/boot/pc98/boot0.5/syscons.s
Normal file
253
sys/boot/pc98/boot0.5/syscons.s
Normal file
@ -0,0 +1,253 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
.code16
|
||||
|
||||
.text
|
||||
#
|
||||
# %al character code
|
||||
# destroyed: %al, %bx
|
||||
#
|
||||
put_character:
|
||||
movw $0xe000, %bx
|
||||
movb ishireso, %ah
|
||||
orb %ah, %ah
|
||||
jne hireso_ch
|
||||
movw $0xa000, %bx
|
||||
hireso_ch:
|
||||
movw %bx, %es
|
||||
xorb %ah, %ah
|
||||
movw curpos, %bx
|
||||
movw %ax, %es:(%bx)
|
||||
xorw %ax, %ax
|
||||
movw %ax, %es
|
||||
ret
|
||||
|
||||
#
|
||||
# %al attribute
|
||||
# destroyed: %ah, %cx
|
||||
#
|
||||
set_attribute:
|
||||
movw $0xe200, %bx
|
||||
movb ishireso, %ah
|
||||
orb %ah, %ah
|
||||
jne hireso_ch
|
||||
movw $0xa200, %bx
|
||||
hireso_attr:
|
||||
movw %bx, %es
|
||||
xorb %ah, %ah
|
||||
movw curpos, %bx
|
||||
movw %ax, %es:(%bx)
|
||||
xorw %bx, %bx
|
||||
movw %bx, %es
|
||||
ret
|
||||
|
||||
#
|
||||
# Put a character
|
||||
# %al: character code
|
||||
# destroyed: %ah, %bx, %cx
|
||||
#
|
||||
.global sc_putc
|
||||
sc_putc:
|
||||
call put_character
|
||||
incw curpos
|
||||
incw curpos
|
||||
cmpw $4000, curpos
|
||||
jng putc_end
|
||||
movw $0, curpos
|
||||
putc_end:
|
||||
ret
|
||||
|
||||
#
|
||||
# Put a null terminated string
|
||||
# %di: pointer to string
|
||||
# destroyed: %ah, %cx, %di
|
||||
#
|
||||
.global sc_puts
|
||||
sc_puts:
|
||||
movb (%di), %al
|
||||
orb %al, %al
|
||||
jz puts_end
|
||||
call sc_putc
|
||||
incw %di
|
||||
jmp sc_puts
|
||||
puts_end:
|
||||
ret
|
||||
|
||||
#
|
||||
# Change the current cursor position
|
||||
# %cx: X
|
||||
# %dx: Y
|
||||
# destroyed: %ax, %bx
|
||||
#
|
||||
.global sc_goto
|
||||
sc_goto:
|
||||
movw %dx, %ax # AX=Y
|
||||
shlw %ax # AX=Y*64
|
||||
shlw %ax
|
||||
shlw %ax
|
||||
shlw %ax
|
||||
shlw %ax
|
||||
shlw %ax
|
||||
movw %dx, %bx # BX=Y
|
||||
shlw %bx # BX=Y*16
|
||||
shlw %bx
|
||||
shlw %bx
|
||||
shlw %bx
|
||||
addw %bx, %ax # AX=Y*64+Y*16=Y*80
|
||||
addw %cx, %ax
|
||||
shlw %ax
|
||||
movw %ax, curpos
|
||||
ret
|
||||
|
||||
#
|
||||
# Clear screen
|
||||
# destroyed: %ax, %bx
|
||||
#
|
||||
.global sc_clean
|
||||
sc_clean:
|
||||
movb $0x16, %ah
|
||||
movw $0xe120, %dx
|
||||
int $0x18 # KBD/CRT BIOS
|
||||
movw $0, curpos
|
||||
ret
|
||||
|
||||
#
|
||||
# Set sttribute code
|
||||
# %al: attribute
|
||||
# %cx: count
|
||||
# destroyed: %ax, %bx, %cx
|
||||
#
|
||||
.global sc_setattr
|
||||
sc_setattr:
|
||||
call set_attribute
|
||||
incw curpos
|
||||
incw curpos
|
||||
loop sc_setattr
|
||||
|
||||
#
|
||||
# Sense the state of shift key
|
||||
# destroyed: %ax
|
||||
#
|
||||
.global sc_getshiftkey
|
||||
sc_getshiftkey:
|
||||
movb $2, %ah # Sense KB_SHIFT_COD
|
||||
int $0x18 # KBD/CRT BIOS
|
||||
xorb %ah, %ah
|
||||
ret
|
||||
|
||||
#
|
||||
# Check KBD buffer
|
||||
#
|
||||
.global sc_iskeypress
|
||||
sc_iskeypress:
|
||||
mov $1, %ah
|
||||
int $0x18 # KBD/CRT BIOS
|
||||
testb $1, %bh
|
||||
jz no_key
|
||||
movw $1, %ax
|
||||
ret
|
||||
no_key:
|
||||
xorw %ax, %ax
|
||||
ret
|
||||
|
||||
#
|
||||
# Read from KBD
|
||||
#
|
||||
.global sc_getc
|
||||
sc_getc:
|
||||
xorb %ah, %ah
|
||||
int $0x18
|
||||
ret
|
||||
|
||||
#
|
||||
# Initialize CRT (normal mode)
|
||||
#
|
||||
init_screen_normal:
|
||||
# Disable graphic screen
|
||||
movb $0x41, %ah
|
||||
int $0x18
|
||||
# Init graphic screen
|
||||
movb $0x42, %al
|
||||
movb $0xc0, %ch
|
||||
int $0x18
|
||||
# 80x25 mode
|
||||
movw $0x0a00, %ax
|
||||
int $0x18
|
||||
ret
|
||||
|
||||
#
|
||||
# Initialize CRT (hireso mode)
|
||||
#
|
||||
init_screen_hireso:
|
||||
# Init RAM window
|
||||
movb $8, %al
|
||||
outb %al, $0x91
|
||||
movb $0x0a, %al
|
||||
outb %al, $0x93
|
||||
# 80x31 mode
|
||||
movw $0x0a00, %ax
|
||||
int $0x18
|
||||
ret
|
||||
|
||||
#
|
||||
# Initialize screen (internal)
|
||||
#
|
||||
init_screen:
|
||||
movb ishireso, %ah
|
||||
orb %ah, %ah
|
||||
jne hireso_ini
|
||||
call init_screen_normal
|
||||
jmp init_next
|
||||
hireso_ini:
|
||||
call init_screen_hireso
|
||||
init_next:
|
||||
movb $0x0c, %ah
|
||||
int $0x18
|
||||
# cursor home and off
|
||||
xorw %dx, %dx
|
||||
movb $0x13, %ah
|
||||
int $0x18
|
||||
movb $0x12, %ah
|
||||
int $0x18
|
||||
ret
|
||||
|
||||
#
|
||||
# Initialize screeen
|
||||
#
|
||||
.global sc_init
|
||||
sc_init:
|
||||
call init_screen
|
||||
call sc_clean
|
||||
movw $0, curpos
|
||||
ret
|
||||
|
||||
.data
|
||||
curpos: .word 0 # Current cursor position
|
19
sys/boot/pc98/boot0/Makefile
Normal file
19
sys/boot/pc98/boot0/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ${BOOT}
|
||||
INTERNALPROG=
|
||||
FILES= ${BOOT}
|
||||
MAN=
|
||||
SRCS= ${BOOT}.s
|
||||
CLEANFILES= ${BOOT}
|
||||
|
||||
BOOT= boot0
|
||||
|
||||
# The base address that we the boot0 code to to run it. Don't change this
|
||||
# unless you are glutton for punishment.
|
||||
BOOT_BOOT0_ORG?= 0x0000
|
||||
ORG=${BOOT_BOOT0_ORG}
|
||||
|
||||
LDFLAGS=${LDFLAGS_BIN}
|
||||
|
||||
.include <bsd.prog.mk>
|
108
sys/boot/pc98/boot0/boot0.s
Normal file
108
sys/boot/pc98/boot0/boot0.s
Normal file
@ -0,0 +1,108 @@
|
||||
# Copyright (c) KATO Takenori, 1999, 2000.
|
||||
#
|
||||
# All rights reserved. Unpublished rights reserved under the copyright
|
||||
# laws of Japan.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
.globl start
|
||||
.code16
|
||||
start:
|
||||
jmp main
|
||||
|
||||
.org 4
|
||||
.ascii "IPL1"
|
||||
.byte 0, 0, 0
|
||||
|
||||
.globl start
|
||||
main:
|
||||
xor %ax, %ax
|
||||
mov %ax, %ds
|
||||
mov (0x584), %al # DA/UA
|
||||
mov %al, %ah
|
||||
and $0xf0, %ah
|
||||
cmp $0x90, %ah
|
||||
je fdd
|
||||
|
||||
# hdd
|
||||
mov $6, %ah
|
||||
mov $0x3000, %bx
|
||||
mov %bx, %es
|
||||
mov $0x2000, %bx
|
||||
xor %cx, %cx
|
||||
xor %dx, %dx
|
||||
xor %bp, %bp
|
||||
int $0x1b
|
||||
jc error_hdd
|
||||
|
||||
push %ax
|
||||
mov %es, %ax
|
||||
add $0x40, %ax
|
||||
mov %ax, %es
|
||||
pop %ax
|
||||
push %es
|
||||
push %bp
|
||||
lret
|
||||
|
||||
# fdd
|
||||
fdd:
|
||||
xor %di, %di
|
||||
fdd_retry:
|
||||
mov $0xd6, %ah
|
||||
mov $0x3000, %bx
|
||||
mov %bx, %es
|
||||
mov $0x2000, %bx
|
||||
mov $0x0200, %cx
|
||||
mov $0x0001, %dx
|
||||
xor %bp, %bp
|
||||
int $0x1b
|
||||
jc error
|
||||
push %ax
|
||||
mov %es, %ax
|
||||
add $0x40, %ax
|
||||
mov %ax, %es
|
||||
pop %ax
|
||||
push %es
|
||||
push %bp
|
||||
lret
|
||||
|
||||
error:
|
||||
or %di, %di
|
||||
jnz error_hdd
|
||||
and $0x0f, %al
|
||||
or $0x30, %al
|
||||
jmp fdd_retry
|
||||
|
||||
error_hdd:
|
||||
jmp error
|
||||
|
||||
.org 0x1fa
|
||||
.byte 0 # defflag_off
|
||||
.byte 0 # defpart_off
|
||||
.byte 1 # menu version
|
||||
.byte 0
|
||||
.word 0xaa55
|
116
sys/boot/pc98/boot2/Makefile
Normal file
116
sys/boot/pc98/boot2/Makefile
Normal file
@ -0,0 +1,116 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
FILES= boot boot1 boot2
|
||||
|
||||
NM?= nm
|
||||
|
||||
BOOT_COMCONSOLE_PORT?= 0x238
|
||||
BOOT_COMCONSOLE_SPEED?= 9600
|
||||
B2SIOFMT?= 0x3
|
||||
|
||||
REL1= 0x700
|
||||
ORG1= 0
|
||||
ORG2= 0x2000
|
||||
|
||||
# Decide level of UFS support.
|
||||
BOOT2_UFS?= UFS1_AND_UFS2
|
||||
#BOOT2_UFS?= UFS2_ONLY
|
||||
#BOOT2_UFS?= UFS1_ONLY
|
||||
|
||||
CFLAGS= -fomit-frame-pointer \
|
||||
-mrtd \
|
||||
-mregparm=3 \
|
||||
-D${BOOT2_UFS} \
|
||||
-DFLAGS=${BOOT_BOOT1_FLAGS} \
|
||||
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
|
||||
-DSIOFMT=${B2SIOFMT} \
|
||||
-DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
|
||||
-I${.CURDIR}/../../.. \
|
||||
-I${.CURDIR}/../../i386/boot2 \
|
||||
-I${.CURDIR}/../../common \
|
||||
-I${.CURDIR}/../btx/lib -I. \
|
||||
-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
|
||||
-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
|
||||
-Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
|
||||
-Winline
|
||||
|
||||
CFLAGS.gcc+= -Os \
|
||||
-fno-guess-branch-probability \
|
||||
-fno-unit-at-a-time \
|
||||
--param max-inline-insns-single=100
|
||||
.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} <= 40201
|
||||
CFLAGS.gcc+= -mno-align-long-strings
|
||||
.endif
|
||||
|
||||
# Set machine type to PC98_SYSTEM_PARAMETER
|
||||
#CFLAGS+= -DSET_MACHINE_TYPE
|
||||
|
||||
# Initialize the bi_bios_geom using the BIOS geometry
|
||||
#CFLAGS+= -DGET_BIOSGEOM
|
||||
|
||||
CFLAGS.clang+= -Oz ${CLANG_OPT_SMALL}
|
||||
|
||||
LD_FLAGS=${LD_FLAGS_BIN}
|
||||
|
||||
# Pick up ../Makefile.inc early.
|
||||
.include <bsd.init.mk>
|
||||
|
||||
.PATH: ${.CURDIR}/../../i386/boot2
|
||||
|
||||
CLEANFILES= boot
|
||||
|
||||
boot: boot1 boot2
|
||||
cat boot1 boot2 > boot
|
||||
|
||||
CLEANFILES+= boot1 boot1.out boot1.o
|
||||
|
||||
boot1: boot1.out
|
||||
${OBJCOPY} -S -O binary boot1.out ${.TARGET}
|
||||
|
||||
boot1.out: boot1.o
|
||||
${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} boot1.o
|
||||
|
||||
CLEANFILES+= boot2 boot2.ld boot2.ldr boot2.bin boot2.out boot2.o \
|
||||
boot2.s boot2.s.tmp boot2.h sio.o
|
||||
|
||||
boot2: boot2.ld
|
||||
@set -- `ls -l boot2.ld`; x=$$((7680-$$5)); \
|
||||
echo "$$x bytes available"; test $$x -ge 0
|
||||
${DD} if=boot2.ld of=${.TARGET} obs=7680 conv=osync
|
||||
|
||||
boot2.ld: boot2.ldr boot2.bin ${BTXKERN}
|
||||
btxld -v -E ${ORG2} -f bin -b ${BTXKERN} -l boot2.ldr \
|
||||
-o ${.TARGET} -P 1 boot2.bin
|
||||
|
||||
boot2.ldr:
|
||||
${DD} if=/dev/zero of=${.TARGET} bs=276 count=1
|
||||
|
||||
boot2.bin: boot2.out
|
||||
${OBJCOPY} -S -O binary boot2.out ${.TARGET}
|
||||
|
||||
boot2.out: ${BTXCRT} boot2.o sio.o
|
||||
${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC}
|
||||
|
||||
boot2.o: boot2.s
|
||||
${CC} ${ACFLAGS} -c boot2.s
|
||||
|
||||
SRCS= boot2.c boot2.h
|
||||
|
||||
boot2.s: boot2.c boot2.h ${.CURDIR}/../../common/ufsread.c
|
||||
${CC} ${CFLAGS} -S -o boot2.s.tmp ${.CURDIR}/boot2.c
|
||||
sed -e '/align/d' -e '/nop/d' < boot2.s.tmp > boot2.s
|
||||
rm -f boot2.s.tmp
|
||||
|
||||
boot2.h: boot1.out
|
||||
${NM} -t d ${.ALLSRC} | awk '/([0-9])+ T (read|putc)/ \
|
||||
{ x = $$1 - ORG1; \
|
||||
printf("#define %sORG %#x\n", toupper($$3), REL1 + x) }' \
|
||||
ORG1=`printf "%d" ${ORG1}` \
|
||||
REL1=`printf "%d" ${REL1}` > ${.TARGET}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
# XXX: clang integrated-as doesn't grok .codeNN directives yet
|
||||
CFLAGS.boot1.S= ${CLANG_NO_IAS}
|
395
sys/boot/pc98/boot2/boot1.S
Normal file
395
sys/boot/pc98/boot2/boot1.S
Normal file
@ -0,0 +1,395 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Memory Locations */
|
||||
.set STACK_OFF,0x6000 # Stack offset
|
||||
.set LOAD_SIZE,8192 # Load size
|
||||
.set DAUA,0x0584 # DA/UA
|
||||
.set MEM_REL,0x700 # Relocation address
|
||||
.set MEM_ARG,0x900 # Arguments
|
||||
.set MEM_BUF,0x8cec # Load area
|
||||
.set MEM_BTX,0x9000 # BTX start
|
||||
.set MEM_JMP,0x9010 # BTX entry point
|
||||
.set MEM_USR,0xa000 # Client start
|
||||
|
||||
/* PC98 machine type from sys/pc98/pc98/pc98_machdep.h */
|
||||
.set MEM_SYS, 0xa100 # System common area segment
|
||||
.set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type
|
||||
.set EPSON_ID, 0x0624 # EPSON machine id
|
||||
|
||||
.set M_NEC_PC98, 0x0001
|
||||
.set M_EPSON_PC98, 0x0002
|
||||
.set M_NOT_H98, 0x0010
|
||||
.set M_H98, 0x0020
|
||||
.set M_NOTE, 0x0040
|
||||
.set M_NORMAL, 0x1000
|
||||
.set M_8M, 0x8000
|
||||
|
||||
/* Partition Constants */
|
||||
.set PRT_OFF,0x1be # Partition offset
|
||||
|
||||
/* Misc. Constants */
|
||||
.set SIZ_PAG,0x1000 # Page size
|
||||
.set SIZ_SEC,0x200 # Sector size
|
||||
|
||||
.set NSECT,0x10
|
||||
|
||||
.globl start
|
||||
.globl read
|
||||
.globl putc
|
||||
.code16
|
||||
|
||||
start: jmp main
|
||||
|
||||
boot_cyl: .org 4
|
||||
.ascii "IPL1 "
|
||||
|
||||
main: cld
|
||||
|
||||
/* Setup the stack */
|
||||
xor %si,%si
|
||||
mov %si,%ss
|
||||
mov $STACK_OFF,%sp
|
||||
|
||||
push %cx
|
||||
|
||||
/* Relocate ourself to MEM_REL */
|
||||
push %cs
|
||||
pop %ds
|
||||
mov %si,%es
|
||||
mov $MEM_REL,%di
|
||||
mov $SIZ_SEC,%cx
|
||||
rep
|
||||
movsb
|
||||
|
||||
/* Transfer PC-9801 system common area */
|
||||
xor %ax,%ax
|
||||
mov %ax,%si
|
||||
mov %ax,%ds
|
||||
mov %ax,%di
|
||||
mov $MEM_SYS,%ax
|
||||
mov %ax,%es
|
||||
mov $0x0600,%cx
|
||||
rep
|
||||
movsb
|
||||
|
||||
/* Transfer EPSON machine type */
|
||||
mov $0xfd00,%ax
|
||||
mov %ax,%ds
|
||||
mov (0x804),%eax
|
||||
and $0x00ffffff,%eax
|
||||
mov %eax,%es:(EPSON_ID)
|
||||
|
||||
/* Set machine type to PC98_SYSTEM_PARAMETER */
|
||||
#ifdef SET_MACHINE_TYPE
|
||||
call set_machine_type
|
||||
#else
|
||||
mov $M_NEC_PC98+M_NOT_H98,%eax
|
||||
mov %eax,%es:(PC98_MACHINE_TYPE)
|
||||
#endif
|
||||
|
||||
/* Setup graphic screen */
|
||||
mov $0x42,%ah /* 640x400 */
|
||||
mov $0xc0,%ch
|
||||
int $0x18
|
||||
mov $0x40,%ah /* graph on */
|
||||
int $0x18
|
||||
|
||||
/* Setup text screen */
|
||||
mov $0x0a00,%ax /* 80x25 */
|
||||
int $0x18
|
||||
mov $0x0c,%ah /* text on */
|
||||
int $0x18
|
||||
mov $0x13,%ah /* cursor home */
|
||||
xor %dx,%dx
|
||||
int $0x18
|
||||
mov $0x11,%ah /* cursor on */
|
||||
int $0x18
|
||||
|
||||
/* Setup keyboard */
|
||||
mov $0x03,%ah
|
||||
int $0x18
|
||||
|
||||
pop %cx
|
||||
|
||||
/* bootstrap passes */
|
||||
xor %edi,%edi
|
||||
mov %di,%ds
|
||||
mov %di,%es
|
||||
mov %cs,%bx
|
||||
cmp $0x1fe0,%bx
|
||||
jz boot_fd
|
||||
cmp $0x1fc0,%bx
|
||||
jnz boot_hd
|
||||
xor %cx,%cx
|
||||
mov (DAUA),%al
|
||||
and $0xf0,%al
|
||||
cmp $0x30,%al
|
||||
jz boot_fd
|
||||
cmp $0x90,%al
|
||||
jnz boot_hd
|
||||
boot_fd: xor %cx,%cx
|
||||
jmp boot_load
|
||||
boot_hd: test %cx,%cx
|
||||
jnz boot_load
|
||||
mov %cs:(boot_cyl),%cx
|
||||
boot_load: mov %cx,MEM_ARG /* Save cylinder number */
|
||||
mov %cx,%di
|
||||
xor %dx,%dx
|
||||
mov $LOAD_SIZE,%bx
|
||||
mov $MEM_BUF,%bp
|
||||
push %cs
|
||||
callw read
|
||||
jc error
|
||||
|
||||
/* Transfer boot2.bin */
|
||||
mov $MEM_BTX,%bx
|
||||
mov 0xa(%bx),%si /* BTX size */
|
||||
add %bx,%si /* start of boot2.bin */
|
||||
mov $MEM_USR+SIZ_PAG*2,%di
|
||||
mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx
|
||||
sub %si,%cx
|
||||
rep
|
||||
movsb
|
||||
|
||||
/* Enable A20 */
|
||||
xor %ax,%ax
|
||||
outb %al,$0xf2
|
||||
mov $0x02,%al
|
||||
outb %al,$0xf6
|
||||
|
||||
/* Start BTX */
|
||||
ljmp $0x0000,$MEM_JMP
|
||||
|
||||
/*
|
||||
* Reads sectors from the disk.
|
||||
* Call with:
|
||||
*
|
||||
* %bx - bytes to read
|
||||
* %cx - cylinder
|
||||
* %dh - head
|
||||
* %dl - sector
|
||||
* %edi - lba
|
||||
* %es:(%bp) - buffer to read data into
|
||||
*/
|
||||
read: xor %ax,%ax
|
||||
mov %ax,%ds
|
||||
mov $0x06,%ah
|
||||
mov (DAUA),%al
|
||||
mov %ax,%si
|
||||
and $0xf0,%al
|
||||
cmp $0x30,%al /* 1.44MB FDD */
|
||||
jz read_fd
|
||||
cmp $0x90,%al /* 1MB FDD */
|
||||
jz read_fd
|
||||
cmp $0xa0,%al /* Is SCSI device? */
|
||||
jnz read_load
|
||||
push %cx
|
||||
mov %si,%cx
|
||||
and $0x0f,%cl
|
||||
inc %cl
|
||||
mov (0x482),%ah
|
||||
shr %cl,%ah /* Is SCSI HDD? */
|
||||
pop %cx
|
||||
jc read_load
|
||||
and $0xff7f,%si /* SCSI MO */
|
||||
mov %di,%cx
|
||||
shr $16,%edi
|
||||
mov %di,%dx
|
||||
jmp read_load
|
||||
read_fd: or $0xd000,%si
|
||||
or $0x0200,%cx
|
||||
inc %dx
|
||||
read_load: mov %si,%ax
|
||||
int $0x1b
|
||||
lret
|
||||
|
||||
/*
|
||||
* Print out the error message, wait for a keypress, and then reboot
|
||||
* the machine.
|
||||
*/
|
||||
error: push %cs
|
||||
pop %ds
|
||||
mov $msg_eread,%si
|
||||
call putstr
|
||||
xor %ax,%ax /* Get keypress */
|
||||
int $0x18
|
||||
xor %ax,%ax /* CPU reset */
|
||||
outb %al,$0xf0
|
||||
halt: hlt
|
||||
jmp halt /* Spin */
|
||||
|
||||
/*
|
||||
* Display a null-terminated string.
|
||||
*/
|
||||
putstr.0: push %cs
|
||||
callw putc
|
||||
putstr: lodsb
|
||||
test %al,%al
|
||||
jne putstr.0
|
||||
ret
|
||||
|
||||
/*
|
||||
* Display a single char.
|
||||
*/
|
||||
putc: pusha
|
||||
xor %dx,%dx
|
||||
mov %dx,%ds
|
||||
mov MEM_REL+cursor-start,%di
|
||||
mov $0xa000,%bx
|
||||
mov %bx,%es
|
||||
mov $(80*2),%cx
|
||||
|
||||
cmp $0x08,%al
|
||||
je putc.bs
|
||||
cmp $0x0d,%al
|
||||
je putc.cr
|
||||
cmp $0x0a,%al
|
||||
je putc.lf
|
||||
cmp $0x5c,%al /* \ */
|
||||
jne 1f
|
||||
mov $0xfc,%al
|
||||
1: movb $0xe1,%es:0x2000(%di)
|
||||
stosw
|
||||
jmp putc.scr
|
||||
putc.bs: test %di,%di
|
||||
jz putc.move
|
||||
dec %di
|
||||
dec %di
|
||||
movb $0xe1,%es:0x2000(%di)
|
||||
movw $0x20,%es:(%di)
|
||||
jmp putc.move
|
||||
putc.cr: mov %di,%ax
|
||||
div %cx
|
||||
sub %dx,%di
|
||||
jmp putc.move
|
||||
putc.lf: add %cx,%di
|
||||
putc.scr: cmp $(80*2*25),%di /* Scroll screen */
|
||||
jb putc.move
|
||||
push %ds
|
||||
mov %bx,%ds
|
||||
mov $(80*2),%si
|
||||
xor %di,%di
|
||||
mov $(80*24/2),%cx
|
||||
rep
|
||||
movsl
|
||||
xor %ax,%ax
|
||||
mov $0x20,%al
|
||||
mov $80,%cl
|
||||
rep
|
||||
stosw
|
||||
pop %ds
|
||||
mov $(80*24*2),%di
|
||||
putc.move: mov %di,MEM_REL+cursor-start /* Move cursor */
|
||||
mov $0x13,%ah
|
||||
mov %di,%dx
|
||||
int $0x18
|
||||
popa
|
||||
lret
|
||||
|
||||
cursor: .word 0
|
||||
|
||||
#ifdef SET_MACHINE_TYPE
|
||||
/*
|
||||
* Set machine type to PC98_SYSTEM_PARAMETER.
|
||||
*/
|
||||
set_machine_type:
|
||||
xor %edx,%edx
|
||||
mov %dx,%ds
|
||||
// mov $MEM_SYS,%ax
|
||||
// mov %ax,%es
|
||||
|
||||
/* Wait V-SYNC */
|
||||
vsync.1: inb $0x60,%al
|
||||
test $0x20,%al
|
||||
jnz vsync.1
|
||||
vsync.2: inb $0x60,%al
|
||||
test $0x20,%al
|
||||
jz vsync.2
|
||||
|
||||
/* ANK 'A' font */
|
||||
xor %al,%al
|
||||
outb %al,$0xa1
|
||||
mov $0x41,%al
|
||||
outb %al,$0xa3
|
||||
|
||||
/* Get 'A' font from CG window */
|
||||
push %ds
|
||||
mov $0xa400,%ax
|
||||
mov %ax,%ds
|
||||
xor %eax,%eax
|
||||
xor %bx,%bx
|
||||
mov $4,%cx
|
||||
font.1: add (%bx),%eax
|
||||
add $4,%bx
|
||||
loop font.1
|
||||
pop %ds
|
||||
cmp $0x6efc58fc,%eax
|
||||
jnz m_epson
|
||||
|
||||
m_pc98: or $M_NEC_PC98,%edx
|
||||
mov $0x0458,%bx
|
||||
mov (%bx),%al
|
||||
test $0x80,%al
|
||||
jz m_not_h98
|
||||
or $M_H98,%edx
|
||||
jmp 1f
|
||||
m_epson: or $M_EPSON_PC98,%edx
|
||||
m_not_h98: or $M_NOT_H98,%edx
|
||||
|
||||
1: inb $0x42,%al
|
||||
test $0x20,%al
|
||||
jz 1f
|
||||
or $M_8M,%edx
|
||||
|
||||
1: mov $0x0400,%bx
|
||||
mov (%bx),%al
|
||||
test $0x80,%al
|
||||
jz 1f
|
||||
or $M_NOTE,%edx
|
||||
|
||||
1: mov $PC98_MACHINE_TYPE,%bx
|
||||
mov %edx,%es:(%bx)
|
||||
ret
|
||||
#endif
|
||||
|
||||
/* Messages */
|
||||
|
||||
msg_eread: .asciz "Error\r\n"
|
||||
|
||||
.org PRT_OFF,0x90
|
||||
|
||||
/* Partition table */
|
||||
|
||||
.fill 0x30,0x1,0x0
|
||||
.byte 0x80, 0x00, 0x01, 0x00
|
||||
.byte 0xa5, 0xff, 0xff, 0xff
|
||||
.byte 0x00, 0x00, 0x00, 0x00
|
||||
.byte 0x50, 0xc3, 0x00, 0x00
|
||||
|
||||
.word 0xaa55 # Magic number
|
803
sys/boot/pc98/boot2/boot2.c
Normal file
803
sys/boot/pc98/boot2/boot2.c
Normal file
@ -0,0 +1,803 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskpc98.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/elf.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <a.out.h>
|
||||
|
||||
#include <btxv86.h>
|
||||
|
||||
#include "boot2.h"
|
||||
#include "lib.h"
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
/* Define to 0 to omit serial support */
|
||||
#ifndef SERIAL
|
||||
#define SERIAL 0
|
||||
#endif
|
||||
|
||||
#define IO_KEYBOARD 1
|
||||
#define IO_SERIAL 2
|
||||
|
||||
#if SERIAL
|
||||
#define DO_KBD (ioctrl & IO_KEYBOARD)
|
||||
#define DO_SIO (ioctrl & IO_SERIAL)
|
||||
#else
|
||||
#define DO_KBD (1)
|
||||
#define DO_SIO (0)
|
||||
#endif
|
||||
|
||||
#define SECOND 1 /* Circa that many ticks in a second. */
|
||||
|
||||
#define ARGS 0x900
|
||||
#define NOPT 14
|
||||
#define NDEV 3
|
||||
|
||||
#define DRV_DISK 0xf0
|
||||
#define DRV_UNIT 0x0f
|
||||
|
||||
#define TYPE_AD 0
|
||||
#define TYPE_DA 1
|
||||
#define TYPE_FD 2
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
|
||||
static const unsigned char flags[NOPT] = {
|
||||
RBX_DUAL,
|
||||
RBX_SERIAL,
|
||||
RBX_ASKNAME,
|
||||
RBX_CDROM,
|
||||
RBX_CONFIG,
|
||||
RBX_KDB,
|
||||
RBX_GDB,
|
||||
RBX_MUTE,
|
||||
RBX_NOINTR,
|
||||
RBX_PAUSE,
|
||||
RBX_QUIET,
|
||||
RBX_DFLTROOT,
|
||||
RBX_SINGLE,
|
||||
RBX_VERBOSE
|
||||
};
|
||||
|
||||
static const char *const dev_nm[NDEV] = {"ad", "da", "fd"};
|
||||
static const unsigned char dev_maj[NDEV] = {30, 4, 2};
|
||||
static const unsigned char dev_daua[NDEV] = {0x80, 0xa0, 0x90};
|
||||
|
||||
static struct dsk {
|
||||
unsigned daua;
|
||||
unsigned type;
|
||||
unsigned disk;
|
||||
unsigned unit;
|
||||
unsigned head;
|
||||
unsigned sec;
|
||||
uint8_t slice;
|
||||
uint8_t part;
|
||||
unsigned start;
|
||||
} dsk;
|
||||
static char cmd[512], cmddup[512], knamebuf[1024];
|
||||
static const char *kname;
|
||||
uint32_t opts;
|
||||
static struct bootinfo bootinfo;
|
||||
#if SERIAL
|
||||
static int comspeed = SIOSPD;
|
||||
static uint8_t ioctrl = IO_KEYBOARD;
|
||||
#endif
|
||||
|
||||
int main(void);
|
||||
void exit(int);
|
||||
static void load(void);
|
||||
static int parse(void);
|
||||
static int dskread(void *, unsigned, unsigned);
|
||||
static void printf(const char *,...);
|
||||
static void putchar(int);
|
||||
static int drvread(void *, unsigned);
|
||||
static int keyhit(unsigned);
|
||||
static int xputc(int);
|
||||
static int xgetc(int);
|
||||
static inline int getc(int);
|
||||
|
||||
static void memcpy(void *, const void *, int);
|
||||
static void
|
||||
memcpy(void *dst, const void *src, int len)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
while (len--)
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
for (; *s1 == *s2 && *s1; s1++, s2++);
|
||||
return (unsigned char)*s1 - (unsigned char)*s2;
|
||||
}
|
||||
|
||||
#define UFS_SMALL_CGBASE
|
||||
#include "ufsread.c"
|
||||
|
||||
static inline int
|
||||
xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
|
||||
{
|
||||
if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
|
||||
printf("Invalid %s\n", "format");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
getstr(void)
|
||||
{
|
||||
char *s;
|
||||
int c;
|
||||
|
||||
s = cmd;
|
||||
for (;;) {
|
||||
switch (c = xgetc(0)) {
|
||||
case 0:
|
||||
break;
|
||||
case '\177':
|
||||
case '\b':
|
||||
if (s > cmd) {
|
||||
s--;
|
||||
printf("\b \b");
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
*s = 0;
|
||||
return;
|
||||
default:
|
||||
if (s - cmd < sizeof(cmd) - 1)
|
||||
*s++ = c;
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
putc(int c)
|
||||
{
|
||||
|
||||
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
|
||||
v86.addr = PUTCORG; /* call to putc in boot1 */
|
||||
v86.eax = c;
|
||||
v86int();
|
||||
v86.ctl = V86_FLAGS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_scsi_hd(void)
|
||||
{
|
||||
|
||||
if ((*(u_char *)PTOV(0x482) >> dsk.unit) & 0x01)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fix_sector_size(void)
|
||||
{
|
||||
u_char *p;
|
||||
|
||||
p = (u_char *)PTOV(0x460 + dsk.unit * 4); /* SCSI equipment parameter */
|
||||
|
||||
if ((p[0] & 0x1f) == 7) { /* SCSI MO */
|
||||
if (!(p[3] & 0x30)) { /* 256B / sector */
|
||||
p[3] |= 0x10; /* forced set 512B / sector */
|
||||
p[3 + 0xa1000] |= 0x10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
get_diskinfo(void)
|
||||
{
|
||||
|
||||
if (dsk.disk == 0x30) { /* 1440KB FD */
|
||||
/* 80 cylinders, 2 heads, 18 sectors */
|
||||
return (80 << 16) | (2 << 8) | 18;
|
||||
} else if (dsk.disk == 0x90) { /* 1200KB FD */
|
||||
/* 80 cylinders, 2 heads, 15 sectors */
|
||||
return (80 << 16) | (2 << 8) | 15;
|
||||
} else if (dsk.disk == 0x80 || is_scsi_hd()) { /* IDE or SCSI HDD */
|
||||
v86.addr = 0x1b;
|
||||
v86.eax = 0x8400 | dsk.daua;
|
||||
v86int();
|
||||
return (v86.ecx << 16) | v86.edx;
|
||||
}
|
||||
|
||||
/* SCSI MO or CD */
|
||||
fix_sector_size(); /* SCSI MO */
|
||||
|
||||
/* other SCSI devices */
|
||||
return (65535 << 16) | (8 << 8) | 32;
|
||||
}
|
||||
|
||||
static void
|
||||
set_dsk(void)
|
||||
{
|
||||
uint32_t di;
|
||||
|
||||
di = get_diskinfo();
|
||||
|
||||
dsk.head = (di >> 8) & 0xff;
|
||||
dsk.sec = di & 0xff;
|
||||
dsk.start = 0;
|
||||
}
|
||||
|
||||
#ifdef GET_BIOSGEOM
|
||||
static uint32_t
|
||||
bd_getbigeom(int bunit)
|
||||
{
|
||||
int hds = 0;
|
||||
int unit = 0x80; /* IDE HDD */
|
||||
u_int addr = 0x55d;
|
||||
|
||||
while (unit < 0xa7) {
|
||||
if (*(u_char *)PTOV(addr) & (1 << (unit & 0x0f)))
|
||||
if (hds++ == bunit)
|
||||
break;
|
||||
|
||||
if (unit >= 0xA0) {
|
||||
int media = ((unsigned *)PTOV(0x460))[unit & 0x0F] & 0x1F;
|
||||
|
||||
if (media == 7 && hds++ == bunit) /* SCSI MO */
|
||||
return(0xFFFE0820); /* C:65535 H:8 S:32 */
|
||||
}
|
||||
if (++unit == 0x84) {
|
||||
unit = 0xA0; /* SCSI HDD */
|
||||
addr = 0x482;
|
||||
}
|
||||
}
|
||||
if (unit == 0xa7)
|
||||
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */
|
||||
v86.addr = 0x1b;
|
||||
v86.eax = 0x8400 | unit;
|
||||
v86int();
|
||||
if (V86_CY(v86.efl))
|
||||
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */
|
||||
return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
check_slice(void)
|
||||
{
|
||||
struct pc98_partition *dp;
|
||||
char *sec;
|
||||
unsigned i, cyl;
|
||||
|
||||
sec = dmadat->secbuf;
|
||||
cyl = *(uint16_t *)PTOV(ARGS);
|
||||
set_dsk();
|
||||
|
||||
if (dsk.type == TYPE_FD)
|
||||
return (WHOLE_DISK_SLICE);
|
||||
if (drvread(sec, PC98_BBSECTOR))
|
||||
return (WHOLE_DISK_SLICE); /* Read error */
|
||||
dp = (void *)(sec + PC98_PARTOFF);
|
||||
for (i = 0; i < PC98_NPARTS; i++) {
|
||||
if (dp[i].dp_mid == DOSMID_386BSD) {
|
||||
if (dp[i].dp_scyl <= cyl && cyl <= dp[i].dp_ecyl)
|
||||
return (BASE_SLICE + i);
|
||||
}
|
||||
}
|
||||
|
||||
return (WHOLE_DISK_SLICE);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#ifdef GET_BIOSGEOM
|
||||
int i;
|
||||
#endif
|
||||
uint8_t autoboot;
|
||||
ufs_ino_t ino;
|
||||
size_t nbyte;
|
||||
|
||||
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
|
||||
dsk.daua = *(uint8_t *)PTOV(0x584);
|
||||
dsk.disk = dsk.daua & DRV_DISK;
|
||||
dsk.unit = dsk.daua & DRV_UNIT;
|
||||
if (dsk.disk == 0x80)
|
||||
dsk.type = TYPE_AD;
|
||||
else if (dsk.disk == 0xa0)
|
||||
dsk.type = TYPE_DA;
|
||||
else /* if (dsk.disk == 0x30 || dsk.disk == 0x90) */
|
||||
dsk.type = TYPE_FD;
|
||||
dsk.slice = check_slice();
|
||||
#ifdef GET_BIOSGEOM
|
||||
for (i = 0; i < N_BIOS_GEOM; i++)
|
||||
bootinfo.bi_bios_geom[i] = bd_getbigeom(i);
|
||||
#endif
|
||||
bootinfo.bi_version = BOOTINFO_VERSION;
|
||||
bootinfo.bi_size = sizeof(bootinfo);
|
||||
|
||||
/* Process configuration file */
|
||||
|
||||
autoboot = 1;
|
||||
|
||||
if ((ino = lookup(PATH_CONFIG)) ||
|
||||
(ino = lookup(PATH_DOTCONFIG))) {
|
||||
nbyte = fsread(ino, cmd, sizeof(cmd) - 1);
|
||||
cmd[nbyte] = '\0';
|
||||
}
|
||||
|
||||
if (*cmd) {
|
||||
memcpy(cmddup, cmd, sizeof(cmd));
|
||||
if (parse())
|
||||
autoboot = 0;
|
||||
if (!OPT_CHECK(RBX_QUIET))
|
||||
printf("%s: %s", PATH_CONFIG, cmddup);
|
||||
/* Do not process this command twice */
|
||||
*cmd = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to exec stage 3 boot loader. If interrupted by a keypress,
|
||||
* or in case of failure, try to load a kernel directly instead.
|
||||
*/
|
||||
|
||||
if (!kname) {
|
||||
kname = PATH_LOADER;
|
||||
if (autoboot && !keyhit(3*SECOND)) {
|
||||
load();
|
||||
kname = PATH_KERNEL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Present the user with the boot2 prompt. */
|
||||
|
||||
for (;;) {
|
||||
if (!autoboot || !OPT_CHECK(RBX_QUIET))
|
||||
printf("\nFreeBSD/pc98 boot\n"
|
||||
"Default: %u:%s(%u,%c)%s\n"
|
||||
"boot: ",
|
||||
dsk.unit, dev_nm[dsk.type], dsk.unit,
|
||||
'a' + dsk.part, kname);
|
||||
if (DO_SIO)
|
||||
sio_flush();
|
||||
if (!autoboot || keyhit(3*SECOND))
|
||||
getstr();
|
||||
else if (!autoboot || !OPT_CHECK(RBX_QUIET))
|
||||
putchar('\n');
|
||||
autoboot = 0;
|
||||
if (parse())
|
||||
putchar('\a');
|
||||
else
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX - Needed for btxld to link the boot2 binary; do not remove. */
|
||||
void
|
||||
exit(int x)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
load(void)
|
||||
{
|
||||
union {
|
||||
struct exec ex;
|
||||
Elf32_Ehdr eh;
|
||||
} hdr;
|
||||
static Elf32_Phdr ep[2];
|
||||
static Elf32_Shdr es[2];
|
||||
caddr_t p;
|
||||
ufs_ino_t ino;
|
||||
uint32_t addr;
|
||||
int k;
|
||||
uint8_t i, j;
|
||||
|
||||
if (!(ino = lookup(kname))) {
|
||||
if (!ls)
|
||||
printf("No %s\n", kname);
|
||||
return;
|
||||
}
|
||||
if (xfsread(ino, &hdr, sizeof(hdr)))
|
||||
return;
|
||||
|
||||
if (N_GETMAGIC(hdr.ex) == ZMAGIC) {
|
||||
addr = hdr.ex.a_entry & 0xffffff;
|
||||
p = PTOV(addr);
|
||||
fs_off = PAGE_SIZE;
|
||||
if (xfsread(ino, p, hdr.ex.a_text))
|
||||
return;
|
||||
p += roundup2(hdr.ex.a_text, PAGE_SIZE);
|
||||
if (xfsread(ino, p, hdr.ex.a_data))
|
||||
return;
|
||||
} else if (IS_ELF(hdr.eh)) {
|
||||
fs_off = hdr.eh.e_phoff;
|
||||
for (j = k = 0; k < hdr.eh.e_phnum && j < 2; k++) {
|
||||
if (xfsread(ino, ep + j, sizeof(ep[0])))
|
||||
return;
|
||||
if (ep[j].p_type == PT_LOAD)
|
||||
j++;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
p = PTOV(ep[i].p_paddr & 0xffffff);
|
||||
fs_off = ep[i].p_offset;
|
||||
if (xfsread(ino, p, ep[i].p_filesz))
|
||||
return;
|
||||
}
|
||||
p += roundup2(ep[1].p_memsz, PAGE_SIZE);
|
||||
bootinfo.bi_symtab = VTOP(p);
|
||||
if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
|
||||
fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
|
||||
(hdr.eh.e_shstrndx + 1);
|
||||
if (xfsread(ino, &es, sizeof(es)))
|
||||
return;
|
||||
for (i = 0; i < 2; i++) {
|
||||
*(Elf32_Word *)p = es[i].sh_size;
|
||||
p += sizeof(es[i].sh_size);
|
||||
fs_off = es[i].sh_offset;
|
||||
if (xfsread(ino, p, es[i].sh_size))
|
||||
return;
|
||||
p += es[i].sh_size;
|
||||
}
|
||||
}
|
||||
addr = hdr.eh.e_entry & 0xffffff;
|
||||
bootinfo.bi_esymtab = VTOP(p);
|
||||
} else {
|
||||
printf("Invalid %s\n", "format");
|
||||
return;
|
||||
}
|
||||
|
||||
bootinfo.bi_kernelname = VTOP(kname);
|
||||
bootinfo.bi_bios_dev = dsk.daua;
|
||||
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
|
||||
MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part),
|
||||
0, 0, 0, VTOP(&bootinfo));
|
||||
}
|
||||
|
||||
static int
|
||||
parse()
|
||||
{
|
||||
char *arg = cmd;
|
||||
char *ep, *p, *q;
|
||||
const char *cp;
|
||||
unsigned int drv;
|
||||
int c, i, j;
|
||||
size_t k;
|
||||
|
||||
while ((c = *arg++)) {
|
||||
if (c == ' ' || c == '\t' || c == '\n')
|
||||
continue;
|
||||
for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
|
||||
ep = p;
|
||||
if (*p)
|
||||
*p++ = 0;
|
||||
if (c == '-') {
|
||||
while ((c = *arg++)) {
|
||||
if (c == 'P') {
|
||||
if (*(uint8_t *)PTOV(0x481) & 0x48) {
|
||||
cp = "yes";
|
||||
} else {
|
||||
opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL);
|
||||
cp = "no";
|
||||
}
|
||||
printf("Keyboard: %s\n", cp);
|
||||
continue;
|
||||
#if SERIAL
|
||||
} else if (c == 'S') {
|
||||
j = 0;
|
||||
while ((unsigned int)(i = *arg++ - '0') <= 9)
|
||||
j = j * 10 + i;
|
||||
if (j > 0 && i == -'0') {
|
||||
comspeed = j;
|
||||
break;
|
||||
}
|
||||
/* Fall through to error below ('S' not in optstr[]). */
|
||||
#endif
|
||||
}
|
||||
for (i = 0; c != optstr[i]; i++)
|
||||
if (i == NOPT - 1)
|
||||
return -1;
|
||||
opts ^= OPT_SET(flags[i]);
|
||||
}
|
||||
#if SERIAL
|
||||
ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
|
||||
OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
|
||||
if (DO_SIO) {
|
||||
if (sio_init(115200 / comspeed) != 0)
|
||||
ioctrl &= ~IO_SERIAL;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
for (q = arg--; *q && *q != '('; q++);
|
||||
if (*q) {
|
||||
drv = -1;
|
||||
if (arg[1] == ':') {
|
||||
drv = *arg - '0';
|
||||
if (drv > 9)
|
||||
return (-1);
|
||||
arg += 2;
|
||||
}
|
||||
if (q - arg != 2)
|
||||
return -1;
|
||||
for (i = 0; arg[0] != dev_nm[i][0] ||
|
||||
arg[1] != dev_nm[i][1]; i++)
|
||||
if (i == NDEV - 1)
|
||||
return -1;
|
||||
dsk.type = i;
|
||||
arg += 3;
|
||||
dsk.unit = *arg - '0';
|
||||
if (arg[1] != ',' || dsk.unit > 9)
|
||||
return -1;
|
||||
arg += 2;
|
||||
dsk.slice = WHOLE_DISK_SLICE;
|
||||
if (arg[1] == ',') {
|
||||
dsk.slice = *arg - '0' + 1;
|
||||
if (dsk.slice > PC98_NPARTS + 1)
|
||||
return -1;
|
||||
arg += 2;
|
||||
}
|
||||
if (arg[1] != ')')
|
||||
return -1;
|
||||
dsk.part = *arg - 'a';
|
||||
if (dsk.part > 7)
|
||||
return (-1);
|
||||
arg += 2;
|
||||
if (drv == -1)
|
||||
drv = dsk.unit;
|
||||
dsk.disk = dev_daua[dsk.type];
|
||||
dsk.daua = dsk.disk | dsk.unit;
|
||||
dsk_meta = 0;
|
||||
}
|
||||
k = ep - arg;
|
||||
if (k > 0) {
|
||||
if (k >= sizeof(knamebuf))
|
||||
return -1;
|
||||
memcpy(knamebuf, arg, k + 1);
|
||||
kname = knamebuf;
|
||||
}
|
||||
}
|
||||
arg = p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dskread(void *buf, unsigned lba, unsigned nblk)
|
||||
{
|
||||
struct pc98_partition *dp;
|
||||
struct disklabel *d;
|
||||
char *sec;
|
||||
unsigned i;
|
||||
uint8_t sl;
|
||||
u_char *p;
|
||||
const char *reason;
|
||||
|
||||
if (!dsk_meta) {
|
||||
sec = dmadat->secbuf;
|
||||
set_dsk();
|
||||
if (dsk.type == TYPE_FD)
|
||||
goto unsliced;
|
||||
if (drvread(sec, PC98_BBSECTOR))
|
||||
return -1;
|
||||
dp = (void *)(sec + PC98_PARTOFF);
|
||||
sl = dsk.slice;
|
||||
if (sl < BASE_SLICE) {
|
||||
for (i = 0; i < PC98_NPARTS; i++)
|
||||
if (dp[i].dp_mid == DOSMID_386BSD) {
|
||||
sl = BASE_SLICE + i;
|
||||
break;
|
||||
}
|
||||
dsk.slice = sl;
|
||||
}
|
||||
if (sl != WHOLE_DISK_SLICE) {
|
||||
dp += sl - BASE_SLICE;
|
||||
if (dp->dp_mid != DOSMID_386BSD) {
|
||||
reason = "slice";
|
||||
goto error;
|
||||
}
|
||||
dsk.start = dp->dp_scyl * dsk.head * dsk.sec +
|
||||
dp->dp_shd * dsk.sec + dp->dp_ssect;
|
||||
}
|
||||
if (drvread(sec, dsk.start + LABELSECTOR))
|
||||
return -1;
|
||||
d = (void *)(sec + LABELOFFSET);
|
||||
if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
|
||||
if (dsk.part != RAW_PART) {
|
||||
reason = "label";
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (dsk.part >= d->d_npartitions ||
|
||||
!d->d_partitions[dsk.part].p_size) {
|
||||
reason = "partition";
|
||||
goto error;
|
||||
}
|
||||
dsk.start += d->d_partitions[dsk.part].p_offset;
|
||||
dsk.start -= d->d_partitions[RAW_PART].p_offset;
|
||||
}
|
||||
unsliced: ;
|
||||
}
|
||||
for (p = buf; nblk; p += 512, lba++, nblk--) {
|
||||
if ((i = drvread(p, dsk.start + lba)))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
printf("Invalid %s\n", reason);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
printf(const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
static char buf[10];
|
||||
char *s;
|
||||
unsigned u;
|
||||
int c;
|
||||
|
||||
va_start(ap, fmt);
|
||||
while ((c = *fmt++)) {
|
||||
if (c == '%') {
|
||||
c = *fmt++;
|
||||
switch (c) {
|
||||
case 'c':
|
||||
putchar(va_arg(ap, int));
|
||||
continue;
|
||||
case 's':
|
||||
for (s = va_arg(ap, char *); *s; s++)
|
||||
putchar(*s);
|
||||
continue;
|
||||
case 'u':
|
||||
u = va_arg(ap, unsigned);
|
||||
s = buf;
|
||||
do
|
||||
*s++ = '0' + u % 10U;
|
||||
while (u /= 10U);
|
||||
while (--s >= buf)
|
||||
putchar(*s);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
putchar(c);
|
||||
}
|
||||
va_end(ap);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
putchar(int c)
|
||||
{
|
||||
if (c == '\n')
|
||||
xputc('\r');
|
||||
xputc(c);
|
||||
}
|
||||
|
||||
static int
|
||||
drvread(void *buf, unsigned lba)
|
||||
{
|
||||
static unsigned c = 0x2d5c7c2f;
|
||||
unsigned bpc, x, cyl, head, sec;
|
||||
|
||||
bpc = dsk.sec * dsk.head;
|
||||
cyl = lba / bpc;
|
||||
x = lba % bpc;
|
||||
head = x / dsk.sec;
|
||||
sec = x % dsk.sec;
|
||||
|
||||
if (!OPT_CHECK(RBX_QUIET)) {
|
||||
xputc(c = c << 8 | c >> 24);
|
||||
xputc('\b');
|
||||
}
|
||||
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
|
||||
v86.addr = READORG; /* call to read in boot1 */
|
||||
v86.ecx = cyl;
|
||||
v86.edx = (head << 8) | sec;
|
||||
v86.edi = lba;
|
||||
v86.ebx = 512;
|
||||
v86.es = VTOPSEG(buf);
|
||||
v86.ebp = VTOPOFF(buf);
|
||||
v86int();
|
||||
v86.ctl = V86_FLAGS;
|
||||
if (V86_CY(v86.efl)) {
|
||||
printf("error %u c/h/s %u/%u/%u lba %u\n", v86.eax >> 8 & 0xff,
|
||||
cyl, head, sec, lba);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
delay(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 800;
|
||||
do {
|
||||
outb(0x5f, 0); /* about 600ns */
|
||||
} while (--i >= 0);
|
||||
}
|
||||
|
||||
static int
|
||||
keyhit(unsigned sec)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (OPT_CHECK(RBX_NOINTR))
|
||||
return 0;
|
||||
for (i = 0; i < sec * 1000; i++) {
|
||||
if (xgetc(1))
|
||||
return 1;
|
||||
delay();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xputc(int c)
|
||||
{
|
||||
if (DO_KBD)
|
||||
putc(c);
|
||||
if (DO_SIO)
|
||||
sio_putc(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
static int
|
||||
getc(int fn)
|
||||
{
|
||||
v86.addr = 0x18;
|
||||
v86.eax = fn << 8;
|
||||
v86int();
|
||||
if (fn)
|
||||
return (v86.ebx >> 8) & 0x01;
|
||||
else
|
||||
return v86.eax & 0xff;
|
||||
}
|
||||
|
||||
static int
|
||||
xgetc(int fn)
|
||||
{
|
||||
if (OPT_CHECK(RBX_NOINTR))
|
||||
return 0;
|
||||
for (;;) {
|
||||
if (DO_KBD && getc(1))
|
||||
return fn ? 1 : getc(0);
|
||||
if (DO_SIO && sio_ischar())
|
||||
return fn ? 1 : sio_getc();
|
||||
if (fn)
|
||||
return 0;
|
||||
}
|
||||
}
|
5
sys/boot/pc98/btx/Makefile
Normal file
5
sys/boot/pc98/btx/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= btx btxldr lib
|
||||
|
||||
.include <bsd.subdir.mk>
|
3
sys/boot/pc98/btx/Makefile.inc
Normal file
3
sys/boot/pc98/btx/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include "../Makefile.inc"
|
33
sys/boot/pc98/btx/btx/Makefile
Normal file
33
sys/boot/pc98/btx/btx/Makefile
Normal file
@ -0,0 +1,33 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= btx
|
||||
INTERNALPROG=
|
||||
MAN=
|
||||
SRCS= btx.S
|
||||
|
||||
.if defined(BOOT_BTX_NOHANG)
|
||||
BOOT_BTX_FLAGS=0x1
|
||||
.else
|
||||
BOOT_BTX_FLAGS=0x0
|
||||
.endif
|
||||
|
||||
CFLAGS+=-DBTX_FLAGS=${BOOT_BTX_FLAGS}
|
||||
CFLAGS+=-I${.CURDIR}/../../../i386/common
|
||||
|
||||
.if defined(BTX_SERIAL)
|
||||
BOOT_COMCONSOLE_PORT?= 0x238
|
||||
BOOT_COMCONSOLE_SPEED?= 9600
|
||||
B2SIOFMT?= 0x3
|
||||
|
||||
CFLAGS+=-DBTX_SERIAL -DSIOPRT=${BOOT_COMCONSOLE_PORT} \
|
||||
-DSIOFMT=${B2SIOFMT} -DSIOSPD=${BOOT_COMCONSOLE_SPEED}
|
||||
.endif
|
||||
|
||||
ORG= 0x9000
|
||||
|
||||
LDFLAGS=${LDFLAGS_BIN}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
# XXX: clang integrated-as doesn't grok .codeNN directives yet
|
||||
CFLAGS.btx.S= ${CLANG_NO_IAS}
|
1104
sys/boot/pc98/btx/btx/btx.S
Normal file
1104
sys/boot/pc98/btx/btx/btx.S
Normal file
File diff suppressed because it is too large
Load Diff
21
sys/boot/pc98/btx/btxldr/Makefile
Normal file
21
sys/boot/pc98/btx/btxldr/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= btxldr
|
||||
INTERNALPROG=
|
||||
MAN=
|
||||
SRCS= btxldr.S
|
||||
|
||||
CFLAGS+=-DLOADER_ADDRESS=${LOADER_ADDRESS}
|
||||
CFLAGS+=-I${.CURDIR}/../../../i386/common
|
||||
|
||||
.if defined(BTXLDR_VERBOSE)
|
||||
CFLAGS+=-DBTXLDR_VERBOSE
|
||||
.endif
|
||||
|
||||
ORG=${LOADER_ADDRESS}
|
||||
LDFLAGS=${LDFLAGS_BIN}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
# XXX: clang integrated-as doesn't grok .codeNN directives yet
|
||||
CFLAGS.btxldr.S= ${CLANG_NO_IAS}
|
430
sys/boot/pc98/btx/btxldr/btxldr.S
Normal file
430
sys/boot/pc98/btx/btxldr/btxldr.S
Normal file
@ -0,0 +1,430 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are freely
|
||||
* permitted provided that the above copyright notice and this
|
||||
* paragraph and the following disclaimer are duplicated in all
|
||||
* such forms.
|
||||
*
|
||||
* This software is provided "AS IS" and without any express or
|
||||
* implied warranties, including, without limitation, the implied
|
||||
* warranties of merchantability and fitness for a particular
|
||||
* purpose.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <bootargs.h>
|
||||
|
||||
/*
|
||||
* 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,start+0x1000 # 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.
|
||||
*/
|
||||
.set SCR_MAT,0xe1 # Mode/attribute
|
||||
.set SCR_COL,0x50 # Columns per row
|
||||
.set SCR_ROW,0x19 # Rows per screen
|
||||
/*
|
||||
* BIOS Data Area locations.
|
||||
*/
|
||||
.set BDA_MEM,0xa1501 # Free memory
|
||||
.set BDA_POS,0xa153e # Cursor position
|
||||
/*
|
||||
* Required by aout gas inadequacy.
|
||||
*/
|
||||
.set SIZ_STUB,0x1a # Size of stub
|
||||
/*
|
||||
* We expect to be loaded by boot2 at the origin defined in ./Makefile.
|
||||
*/
|
||||
.globl start
|
||||
/*
|
||||
* BTX program loader for ELF clients.
|
||||
*/
|
||||
start: cld # String ops inc
|
||||
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)
|
||||
movl $m_logo,%esi # Identify
|
||||
call putstr # ourselves
|
||||
movzwl BDA_MEM,%eax # Get base memory
|
||||
andl $0x7,%eax
|
||||
incl %eax
|
||||
shll $0x11,%eax # in bytes
|
||||
movl %eax,%ebp # Base of user stack
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_mem,%esi # Display
|
||||
call hexout # amount of
|
||||
call putstr # base memory
|
||||
#endif
|
||||
lgdt gdtdesc # Load new GDT
|
||||
/*
|
||||
* Relocate caller's arguments.
|
||||
*/
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_esp,%esi # Display
|
||||
movl %esp,%eax # caller
|
||||
call hexout # stack
|
||||
call putstr # pointer
|
||||
movl $m_args,%esi # Format string
|
||||
leal 0x4(%esp),%ebx # First argument
|
||||
movl $0x6,%ecx # Count
|
||||
start.1: movl (%ebx),%eax # Get argument and
|
||||
addl $0x4,%ebx # bump pointer
|
||||
call hexout # Display it
|
||||
loop start.1 # Till done
|
||||
call putstr # End message
|
||||
#endif
|
||||
movl BA_BOOTINFO+4(%esp),%esi # Source: bootinfo
|
||||
cmpl $0x0, %esi # If the bootinfo pointer
|
||||
je start_null_bi # is null, don't copy it
|
||||
movl BI_SIZE(%esi),%ecx # Allocate space
|
||||
subl %ecx,%ebp # for bootinfo
|
||||
movl %ebp,%edi # Destination
|
||||
rep # Copy
|
||||
movsb # it
|
||||
movl %ebp,BA_BOOTINFO+4(%esp) # Update pointer
|
||||
movl %edi,%ebp # Restore base pointer
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_rel_bi,%esi # Display
|
||||
movl %ebp,%eax # bootinfo
|
||||
call hexout # relocation
|
||||
call putstr # message
|
||||
#endif
|
||||
start_null_bi: movl $BOOTARGS_SIZE,%ecx # Fixed size of arguments
|
||||
testl $KARGS_FLAGS_EXTARG, BA_BOOTFLAGS+4(%esp) # Check for extra data
|
||||
jz start_fixed # Skip if the flag is not set
|
||||
addl BOOTARGS_SIZE+4(%esp),%ecx # Add size of variable args
|
||||
start_fixed: subl $ARGOFF,%ebp # Place args at fixed offset
|
||||
leal 0x4(%esp),%esi # Source
|
||||
movl %ebp,%edi # Destination
|
||||
rep # Copy
|
||||
movsb # them
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_rel_args,%esi # Display
|
||||
movl %ebp,%eax # argument
|
||||
call hexout # relocation
|
||||
call putstr # message
|
||||
#endif
|
||||
/*
|
||||
* 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 load address
|
||||
movzwl 0xa(%ebx),%ecx # Image size
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
pushl %ecx # Save image size
|
||||
#endif
|
||||
rep # Relocate
|
||||
movsb # BTX
|
||||
movl %esi,%ebx # Keep place
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_rel_btx,%esi # Restore
|
||||
popl %eax # parameters
|
||||
call hexout # and
|
||||
#endif
|
||||
popl %ebp # display
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl %ebp,%eax # the
|
||||
call hexout # relocation
|
||||
call putstr # message
|
||||
#endif
|
||||
addl $PAG_SIZ,%ebp # Display
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_base,%esi # the
|
||||
movl %ebp,%eax # user
|
||||
call hexout # base
|
||||
call putstr # address
|
||||
#endif
|
||||
/*
|
||||
* 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:
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_elf,%esi # Display ELF
|
||||
call putstr # message
|
||||
movl $m_segs,%esi # Format string
|
||||
#endif
|
||||
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
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl 0x4(%edx),%eax # Display
|
||||
call hexout # p_offset
|
||||
movl 0x8(%edx),%eax # Display
|
||||
call hexout # p_vaddr
|
||||
movl 0x10(%edx),%eax # Display
|
||||
call hexout # p_filesz
|
||||
movl 0x14(%edx),%eax # Display
|
||||
call hexout # p_memsz
|
||||
call putstr # End message
|
||||
#endif
|
||||
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:
|
||||
#ifdef BTXLDR_VERBOSE
|
||||
movl $m_done,%esi # Display done
|
||||
call putstr # message
|
||||
#endif
|
||||
movl $start.8,%esi # Real mode stub
|
||||
movl $MEM_STUB,%edi # Destination
|
||||
movl $start.9-start.8,%ecx # Size
|
||||
rep # Relocate
|
||||
movsb # it
|
||||
ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
|
||||
.code16
|
||||
start.8: xorw %ax,%ax # Data
|
||||
movb $SEL_RDATA,%al # selector
|
||||
movw %ax,%ss # Reload SS
|
||||
movw %ax,%ds # Reset
|
||||
movw %ax,%es # other
|
||||
movw %ax,%fs # segment
|
||||
movw %ax,%gs # limits
|
||||
movl %cr0,%eax # Switch to
|
||||
decw %ax # real
|
||||
movl %eax,%cr0 # mode
|
||||
ljmp $0,$MEM_ENTRY # Jump to BTX entry point
|
||||
start.9:
|
||||
.code32
|
||||
/*
|
||||
* Output message [ESI] followed by EAX in hex.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
movl $0xa0000,%edi # Regen buffer (color)
|
||||
putchr.1: cmpb $0xa,%al # New line?
|
||||
je putchr.2 # Yes
|
||||
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
|
||||
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
|
||||
xorb %ah,%ah
|
||||
movb $SCR_COL,%cl # Columns to clear
|
||||
rep # Clear
|
||||
stosw # line
|
||||
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
|
||||
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
|
10
sys/boot/pc98/btx/lib/Makefile
Normal file
10
sys/boot/pc98/btx/lib/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= crt0.o
|
||||
INTERNALPROG=
|
||||
MAN=
|
||||
SRCS= btxcsu.S btxsys.s btxv86.s
|
||||
CFLAGS+=-I${.CURDIR}/../../../i386/common
|
||||
LDFLAGS=-Wl,-r
|
||||
|
||||
.include <bsd.prog.mk>
|
49
sys/boot/pc98/btx/lib/btxcsu.S
Normal file
49
sys/boot/pc98/btx/lib/btxcsu.S
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright (c) 1998 Robert Nordier
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms are freely
|
||||
# permitted provided that the above copyright notice and this
|
||||
# paragraph and the following disclaimer are duplicated in all
|
||||
# such forms.
|
||||
#
|
||||
# This software is provided "AS IS" and without any express or
|
||||
# implied warranties, including, without limitation, the implied
|
||||
# warranties of merchantability and fitness for a particular
|
||||
# purpose.
|
||||
#
|
||||
|
||||
# $FreeBSD$
|
||||
|
||||
#include <bootargs.h>
|
||||
|
||||
#
|
||||
# BTX C startup code (ELF).
|
||||
#
|
||||
|
||||
#
|
||||
# Globals.
|
||||
#
|
||||
.global _start
|
||||
#
|
||||
# Client entry point.
|
||||
#
|
||||
_start: cld
|
||||
pushl %eax
|
||||
movl $_edata,%edi
|
||||
movl $_end,%ecx
|
||||
subl %edi, %ecx
|
||||
xorb %al, %al
|
||||
rep
|
||||
stosb
|
||||
popl __base
|
||||
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.
|
||||
#
|
||||
|
||||
# $FreeBSD$
|
||||
|
||||
#
|
||||
# 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
|
67
sys/boot/pc98/btx/lib/btxv86.h
Normal file
67
sys/boot/pc98/btx/lib/btxv86.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are freely
|
||||
* permitted provided that the above copyright notice and this
|
||||
* paragraph and the following disclaimer are duplicated in all
|
||||
* such forms.
|
||||
*
|
||||
* This software is provided "AS IS" and without any express or
|
||||
* implied warranties, including, without limitation, the implied
|
||||
* warranties of merchantability and fitness for a particular
|
||||
* purpose.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _BTXV86_H_
|
||||
#define _BTXV86_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/psl.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)
|
||||
|
||||
#define V86_CY(x) ((x) & PSL_C)
|
||||
#define V86_ZR(x) ((x) & PSL_Z)
|
||||
|
||||
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.
|
||||
#
|
||||
|
||||
# $FreeBSD$
|
||||
|
||||
#
|
||||
# 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
|
18
sys/boot/pc98/cdboot/Makefile
Normal file
18
sys/boot/pc98/cdboot/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= cdboot
|
||||
STRIP=
|
||||
BINMODE=${NOBINMODE}
|
||||
MAN=
|
||||
SRCS= ${PROG}.S
|
||||
|
||||
CFLAGS+=-I${.CURDIR}/../../i386/common
|
||||
|
||||
ORG= 0x0000
|
||||
|
||||
LDFLAGS=${LDFLAGS_BIN}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
# XXX: clang integrated-as doesn't grok .codeNN directives yet
|
||||
CFLAGS.cdboot.S= ${CLANG_NO_IAS}
|
805
sys/boot/pc98/cdboot/cdboot.S
Normal file
805
sys/boot/pc98/cdboot/cdboot.S
Normal file
@ -0,0 +1,805 @@
|
||||
#
|
||||
# Copyright (c) 2006 TAKAHASHI Yoshihiro <nyan@FreeBSD.org>
|
||||
# Copyright (c) 2001 John Baldwin <jhb@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.
|
||||
#
|
||||
|
||||
# $FreeBSD$
|
||||
|
||||
#
|
||||
# Basically, we first create a set of boot arguments to pass to the loaded
|
||||
# binary. Then we attempt to load /boot/loader from the CD we were booted
|
||||
# off of.
|
||||
#
|
||||
|
||||
#include <bootargs.h>
|
||||
|
||||
#
|
||||
# Memory locations.
|
||||
#
|
||||
.set STACK_OFF,0x6000 # Stack offset
|
||||
.set LOAD_SEG,0x0700 # Load segment
|
||||
.set LOAD_SIZE,2048 # Load size
|
||||
.set DAUA,0x0584 # DA/UA
|
||||
|
||||
.set MEM_PAGE_SIZE,0x1000 # memory page size, 4k
|
||||
.set MEM_ARG,0x900 # Arguments at start
|
||||
.set MEM_ARG_BTX,0xa100 # Where we move them to so the
|
||||
# BTX client can see them
|
||||
.set MEM_ARG_SIZE,0x18 # Size of the arguments
|
||||
.set MEM_BTX_ADDRESS,0x9000 # where BTX lives
|
||||
.set MEM_BTX_ENTRY,0x9010 # where BTX starts to execute
|
||||
.set MEM_BTX_OFFSET,MEM_PAGE_SIZE # offset of BTX in the loader
|
||||
.set MEM_BTX_CLIENT,0xa000 # where BTX clients live
|
||||
#
|
||||
# PC98 machine type from sys/pc98/pc98/pc98_machdep.h
|
||||
#
|
||||
.set MEM_SYS, 0xa100 # System common area segment
|
||||
.set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type
|
||||
.set EPSON_ID, 0x0624 # EPSON machine id
|
||||
|
||||
.set M_NEC_PC98, 0x0001
|
||||
.set M_EPSON_PC98, 0x0002
|
||||
.set M_NOT_H98, 0x0010
|
||||
.set M_H98, 0x0020
|
||||
.set M_NOTE, 0x0040
|
||||
.set M_NORMAL, 0x1000
|
||||
.set M_8M, 0x8000
|
||||
#
|
||||
# Signature Constants
|
||||
#
|
||||
.set SIG1_OFF,0x1fe # Signature offset
|
||||
.set SIG2_OFF,0x7fe # Signature offset
|
||||
#
|
||||
# a.out header fields
|
||||
#
|
||||
.set AOUT_TEXT,0x04 # text segment size
|
||||
.set AOUT_DATA,0x08 # data segment size
|
||||
.set AOUT_BSS,0x0c # zero'd BSS size
|
||||
.set AOUT_SYMBOLS,0x10 # symbol table
|
||||
.set AOUT_ENTRY,0x14 # entry point
|
||||
.set AOUT_HEADER,MEM_PAGE_SIZE # size of the a.out header
|
||||
#
|
||||
# Segment selectors.
|
||||
#
|
||||
.set SEL_SDATA,0x8 # Supervisor data
|
||||
.set SEL_RDATA,0x10 # Real mode data
|
||||
.set SEL_SCODE,0x18 # PM-32 code
|
||||
.set SEL_SCODE16,0x20 # PM-16 code
|
||||
#
|
||||
# BTX constants
|
||||
#
|
||||
.set INT_SYS,0x30 # BTX syscall interrupt
|
||||
#
|
||||
# Constants for reading from the CD.
|
||||
#
|
||||
.set ERROR_TIMEOUT,0x90 # BIOS timeout on read
|
||||
.set NUM_RETRIES,3 # Num times to retry
|
||||
.set SECTOR_SIZE,0x800 # size of a sector
|
||||
.set SECTOR_SHIFT,11 # number of place to shift
|
||||
.set BUFFER_LEN,0x100 # number of sectors in buffer
|
||||
.set MAX_READ,0xf800 # max we can read at a time
|
||||
.set MAX_READ_SEC,MAX_READ >> SECTOR_SHIFT
|
||||
.set MEM_READ_BUFFER,0x9000 # buffer to read from CD
|
||||
.set MEM_VOLDESC,MEM_READ_BUFFER # volume descriptor
|
||||
.set MEM_DIR,MEM_VOLDESC+SECTOR_SIZE # Lookup buffer
|
||||
.set VOLDESC_LBA,0x10 # LBA of vol descriptor
|
||||
.set VD_PRIMARY,1 # Primary VD
|
||||
.set VD_END,255 # VD Terminator
|
||||
.set VD_ROOTDIR,156 # Offset of Root Dir Record
|
||||
.set DIR_LEN,0 # Offset of Dir Record length
|
||||
.set DIR_EA_LEN,1 # Offset of EA length
|
||||
.set DIR_EXTENT,2 # Offset of 64-bit LBA
|
||||
.set DIR_SIZE,10 # Offset of 64-bit length
|
||||
.set DIR_NAMELEN,32 # Offset of 8-bit name len
|
||||
.set DIR_NAME,33 # Offset of dir name
|
||||
|
||||
#
|
||||
# Program start.
|
||||
#
|
||||
.code16
|
||||
.globl start
|
||||
|
||||
start: jmp main
|
||||
|
||||
.org 4
|
||||
.ascii "IPL1 "
|
||||
|
||||
main: cld
|
||||
|
||||
/* Setup the stack */
|
||||
xor %ax,%ax
|
||||
mov %ax,%ss
|
||||
mov $STACK_OFF,%sp
|
||||
|
||||
push %ecx
|
||||
|
||||
/* Setup graphic screen */
|
||||
mov $0x42,%ah # 640x400
|
||||
mov $0xc0,%ch
|
||||
int $0x18
|
||||
mov $0x40,%ah # graph on
|
||||
int $0x18
|
||||
|
||||
/* Setup text screen */
|
||||
mov $0x0a00,%ax # 80x25
|
||||
int $0x18
|
||||
mov $0x0c,%ah # text on
|
||||
int $0x18
|
||||
mov $0x13,%ah # cursor home
|
||||
xor %dx,%dx
|
||||
int $0x18
|
||||
mov $0x11,%ah # cursor on
|
||||
int $0x18
|
||||
|
||||
/* Setup keyboard */
|
||||
mov $0x03,%ah
|
||||
int $0x18
|
||||
|
||||
/* Transfer PC-9801 system common area */
|
||||
xor %ax,%ax
|
||||
mov %ax,%si
|
||||
mov %ax,%ds
|
||||
mov %ax,%di
|
||||
mov $MEM_SYS,%ax
|
||||
mov %ax,%es
|
||||
mov $0x0600,%cx
|
||||
rep
|
||||
movsb
|
||||
|
||||
/* Transfer EPSON machine type */
|
||||
mov $0xfd00,%ax
|
||||
mov %ax,%ds
|
||||
mov (0x804),%eax
|
||||
and $0x00ffffff,%eax
|
||||
mov %eax,%es:(EPSON_ID)
|
||||
|
||||
/* Set machine type to PC98_SYSTEM_PARAMETER */
|
||||
call machine_check
|
||||
|
||||
/* Load cdboot */
|
||||
xor %ax,%ax
|
||||
mov %ax,%ds
|
||||
mov $0x06,%ah /* Read data */
|
||||
mov (DAUA),%al /* Read drive */
|
||||
pop %ecx /* cylinder */
|
||||
xor %dx,%dx /* head / sector */
|
||||
mov $LOAD_SEG,%bx /* Load address */
|
||||
mov %bx,%es
|
||||
xor %bp,%bp
|
||||
mov $LOAD_SIZE,%bx /* Load size */
|
||||
int $0x1b
|
||||
mov $msg_readerr,%si
|
||||
jc error
|
||||
|
||||
/* Jump to cdboot */
|
||||
ljmp $LOAD_SEG,$cdboot
|
||||
|
||||
#
|
||||
# Set machine type to PC98_SYSTEM_PARAMETER.
|
||||
#
|
||||
machine_check: xor %edx,%edx
|
||||
mov %dx,%ds
|
||||
mov $MEM_SYS,%ax
|
||||
mov %ax,%es
|
||||
|
||||
/* Wait V-SYNC */
|
||||
vsync.1: inb $0x60,%al
|
||||
test $0x20,%al
|
||||
jnz vsync.1
|
||||
vsync.2: inb $0x60,%al
|
||||
test $0x20,%al
|
||||
jz vsync.2
|
||||
|
||||
/* ANK 'A' font */
|
||||
xor %al,%al
|
||||
outb %al,$0xa1
|
||||
mov $0x41,%al
|
||||
outb %al,$0xa3
|
||||
|
||||
/* Get 'A' font from CG window */
|
||||
push %ds
|
||||
mov $0xa400,%ax
|
||||
mov %ax,%ds
|
||||
xor %eax,%eax
|
||||
xor %bx,%bx
|
||||
mov $4,%cx
|
||||
font.1: add (%bx),%eax
|
||||
add $4,%bx
|
||||
loop font.1
|
||||
pop %ds
|
||||
cmp $0x6efc58fc,%eax
|
||||
jnz m_epson
|
||||
|
||||
m_pc98: or $M_NEC_PC98,%edx
|
||||
mov $0x0458,%bx
|
||||
mov (%bx),%al
|
||||
test $0x80,%al
|
||||
jz m_not_h98
|
||||
or $M_H98,%edx
|
||||
jmp 1f
|
||||
m_epson: or $M_EPSON_PC98,%edx
|
||||
m_not_h98: or $M_NOT_H98,%edx
|
||||
|
||||
1: inb $0x42,%al
|
||||
test $0x20,%al
|
||||
jz 1f
|
||||
or $M_8M,%edx
|
||||
|
||||
1: mov $0x0400,%bx
|
||||
mov (%bx),%al
|
||||
test $0x80,%al
|
||||
jz 1f
|
||||
or $M_NOTE,%edx
|
||||
|
||||
1: mov $PC98_MACHINE_TYPE,%bx
|
||||
mov %edx,%es:(%bx)
|
||||
ret
|
||||
|
||||
#
|
||||
# Print out the error message at [SI], wait for a keypress, and then
|
||||
# reboot the machine.
|
||||
#
|
||||
error: call putstr
|
||||
mov $msg_keypress,%si
|
||||
call putstr
|
||||
xor %ax,%ax # Get keypress
|
||||
int $0x18
|
||||
xor %ax,%ax # CPU reset
|
||||
outb %al,$0xf0
|
||||
halt: hlt
|
||||
jmp halt # Spin
|
||||
|
||||
#
|
||||
# Display a null-terminated string at [SI].
|
||||
#
|
||||
# Trashes: AX, BX, CX, DX, SI, DI
|
||||
#
|
||||
putstr: push %ds
|
||||
push %es
|
||||
mov %cs,%ax
|
||||
mov %ax,%ds
|
||||
mov $0xa000,%ax
|
||||
mov %ax,%es
|
||||
mov cursor,%di
|
||||
mov $0x00e1,%bx # Attribute
|
||||
mov $160,%cx
|
||||
putstr.0: lodsb
|
||||
testb %al,%al
|
||||
jz putstr.done
|
||||
cmp $0x0d,%al
|
||||
jz putstr.cr
|
||||
cmp $0x0a,%al
|
||||
jz putstr.lf
|
||||
mov %bl,%es:0x2000(%di)
|
||||
stosb
|
||||
inc %di
|
||||
jmp putstr.move
|
||||
putstr.cr: xor %dx,%dx
|
||||
mov %di,%ax
|
||||
div %cx
|
||||
sub %dx,%di
|
||||
jmp putstr.move
|
||||
putstr.lf: add %cx,%di
|
||||
putstr.move: mov %di,%dx
|
||||
mov $0x13,%ah # Move cursor
|
||||
int $0x18
|
||||
jmp putstr.0
|
||||
putstr.done: mov %di,cursor
|
||||
pop %es
|
||||
pop %ds
|
||||
ret
|
||||
|
||||
#
|
||||
# Display a single char at [AL], but don't move a cursor.
|
||||
#
|
||||
putc: push %es
|
||||
push %di
|
||||
push %bx
|
||||
mov $0xa000,%bx
|
||||
mov %bx,%es
|
||||
mov cursor,%di
|
||||
mov $0xe1,%bl # Attribute
|
||||
mov %bl,%es:0x2000(%di)
|
||||
stosb
|
||||
pop %bx
|
||||
pop %di
|
||||
pop %es
|
||||
ret
|
||||
|
||||
msg_readerr: .asciz "Read Error\r\n"
|
||||
msg_keypress: .asciz "\r\nPress any key to reboot\r\n"
|
||||
|
||||
/* Boot signature */
|
||||
|
||||
.org SIG1_OFF,0x90
|
||||
|
||||
.word 0xaa55 # Magic number
|
||||
|
||||
#
|
||||
# cdboot
|
||||
#
|
||||
cdboot: mov %cs,%ax
|
||||
mov %ax,%ds
|
||||
xor %ax,%ax
|
||||
mov %ax,%es
|
||||
mov %es:(DAUA),%al # Save BIOS boot device
|
||||
mov %al,drive
|
||||
mov %cx,cylinder # Save BIOS boot cylinder
|
||||
|
||||
mov $msg_welcome,%si # %ds:(%si) -> welcome message
|
||||
call putstr # display the welcome message
|
||||
#
|
||||
# Setup the arguments that the loader is expecting from boot[12]
|
||||
#
|
||||
mov $msg_bootinfo,%si # %ds:(%si) -> boot args message
|
||||
call putstr # display the message
|
||||
mov $MEM_ARG,%bx # %ds:(%bx) -> boot args
|
||||
mov %bx,%di # %es:(%di) -> boot args
|
||||
xor %eax,%eax # zero %eax
|
||||
mov $(MEM_ARG_SIZE/4),%cx # Size of arguments in 32-bit
|
||||
# dwords
|
||||
rep # Clear the arguments
|
||||
stosl # to zero
|
||||
mov drive,%dl # Store BIOS boot device
|
||||
mov %dl,%es:0x4(%bx) # in kargs->bootdev
|
||||
or $KARGS_FLAGS_CD,%es:0x8(%bx) # kargs->bootflags |=
|
||||
# KARGS_FLAGS_CD
|
||||
#
|
||||
# Load Volume Descriptor
|
||||
#
|
||||
mov $VOLDESC_LBA,%eax # Set LBA of first VD
|
||||
load_vd: push %eax # Save %eax
|
||||
mov $1,%dh # One sector
|
||||
mov $MEM_VOLDESC,%ebx # Destination
|
||||
call read # Read it in
|
||||
cmpb $VD_PRIMARY,%es:(%bx) # Primary VD?
|
||||
je have_vd # Yes
|
||||
pop %eax # Prepare to
|
||||
inc %eax # try next
|
||||
cmpb $VD_END,%es:(%bx) # Last VD?
|
||||
jne load_vd # No, read next
|
||||
mov $msg_novd,%si # No VD
|
||||
jmp error # Halt
|
||||
have_vd: # Have Primary VD
|
||||
#
|
||||
# Try to look up the loader binary using the paths in the loader_paths
|
||||
# array.
|
||||
#
|
||||
mov $loader_paths,%si # Point to start of array
|
||||
lookup_path: push %si # Save file name pointer
|
||||
call lookup # Try to find file
|
||||
pop %di # Restore file name pointer
|
||||
jnc lookup_found # Found this file
|
||||
push %es
|
||||
mov %cs,%ax
|
||||
mov %ax,%es
|
||||
xor %al,%al # Look for next
|
||||
mov $0xffff,%cx # path name by
|
||||
repnz # scanning for
|
||||
scasb # nul char
|
||||
pop %es
|
||||
mov %di,%si # Point %si at next path
|
||||
mov (%si),%al # Get first char of next path
|
||||
or %al,%al # Is it double nul?
|
||||
jnz lookup_path # No, try it.
|
||||
mov $msg_failed,%si # Failed message
|
||||
jmp error # Halt
|
||||
lookup_found: # Found a loader file
|
||||
#
|
||||
# Load the binary into the buffer. Due to real mode addressing limitations
|
||||
# we have to read it in 64k chunks.
|
||||
#
|
||||
mov %es:DIR_SIZE(%bx),%eax # Read file length
|
||||
add $SECTOR_SIZE-1,%eax # Convert length to sectors
|
||||
shr $SECTOR_SHIFT,%eax
|
||||
cmp $BUFFER_LEN,%eax
|
||||
jbe load_sizeok
|
||||
mov $msg_load2big,%si # Error message
|
||||
jmp error
|
||||
load_sizeok: movzbw %al,%cx # Num sectors to read
|
||||
mov %es:DIR_EXTENT(%bx),%eax # Load extent
|
||||
xor %edx,%edx
|
||||
mov %es:DIR_EA_LEN(%bx),%dl
|
||||
add %edx,%eax # Skip extended
|
||||
mov $MEM_READ_BUFFER,%ebx # Read into the buffer
|
||||
load_loop: mov %cl,%dh
|
||||
cmp $MAX_READ_SEC,%cl # Truncate to max read size
|
||||
jbe load_notrunc
|
||||
mov $MAX_READ_SEC,%dh
|
||||
load_notrunc: sub %dh,%cl # Update count
|
||||
push %eax # Save
|
||||
call read # Read it in
|
||||
pop %eax # Restore
|
||||
add $MAX_READ_SEC,%eax # Update LBA
|
||||
add $MAX_READ,%ebx # Update dest addr
|
||||
jcxz load_done # Done?
|
||||
jmp load_loop # Keep going
|
||||
load_done:
|
||||
#
|
||||
# Turn on the A20 address line
|
||||
#
|
||||
xor %ax,%ax # Turn A20 on
|
||||
outb %al,$0xf2
|
||||
mov $0x02,%al
|
||||
outb %al,$0xf6
|
||||
#
|
||||
# Relocate the loader and BTX using a very lazy protected mode
|
||||
#
|
||||
mov $msg_relocate,%si # Display the
|
||||
call putstr # relocation message
|
||||
mov %es:(MEM_READ_BUFFER+AOUT_ENTRY),%edi # %edi is the destination
|
||||
mov $(MEM_READ_BUFFER+AOUT_HEADER),%esi # %esi is
|
||||
# the start of the text
|
||||
# segment
|
||||
mov %es:(MEM_READ_BUFFER+AOUT_TEXT),%ecx # %ecx = length of the text
|
||||
# segment
|
||||
push %edi # Save entry point for later
|
||||
lgdt gdtdesc # setup our own gdt
|
||||
cli # turn off interrupts
|
||||
mov %cr0,%eax # Turn on
|
||||
or $0x1,%al # protected
|
||||
mov %eax,%cr0 # mode
|
||||
ljmp $SEL_SCODE,$pm_start # long jump to clear the
|
||||
# instruction pre-fetch queue
|
||||
.code32
|
||||
pm_start: mov $SEL_SDATA,%ax # Initialize
|
||||
mov %ax,%ds # %ds and
|
||||
mov %ax,%es # %es to a flat selector
|
||||
rep # Relocate the
|
||||
movsb # text segment
|
||||
add $(MEM_PAGE_SIZE - 1),%edi # pad %edi out to a new page
|
||||
and $~(MEM_PAGE_SIZE - 1),%edi # for the data segment
|
||||
mov MEM_READ_BUFFER+AOUT_DATA,%ecx # size of the data segment
|
||||
rep # Relocate the
|
||||
movsb # data segment
|
||||
mov MEM_READ_BUFFER+AOUT_BSS,%ecx # size of the bss
|
||||
xor %eax,%eax # zero %eax
|
||||
add $3,%cl # round %ecx up to
|
||||
shr $2,%ecx # a multiple of 4
|
||||
rep # zero the
|
||||
stosl # bss
|
||||
mov MEM_READ_BUFFER+AOUT_ENTRY,%esi # %esi -> relocated loader
|
||||
add $MEM_BTX_OFFSET,%esi # %esi -> BTX in the loader
|
||||
mov $MEM_BTX_ADDRESS,%edi # %edi -> where BTX needs to go
|
||||
movzwl 0xa(%esi),%ecx # %ecx -> length of BTX
|
||||
rep # Relocate
|
||||
movsb # BTX
|
||||
ljmp $SEL_SCODE16,$pm_16 # Jump to 16-bit PM
|
||||
.code16
|
||||
pm_16: mov $SEL_RDATA,%ax # Initialize
|
||||
mov %ax,%ds # %ds and
|
||||
mov %ax,%es # %es to a real mode selector
|
||||
mov %cr0,%eax # Turn off
|
||||
and $~0x1,%al # protected
|
||||
mov %eax,%cr0 # mode
|
||||
ljmp $LOAD_SEG,$pm_end # Long jump to clear the
|
||||
# instruction pre-fetch queue
|
||||
pm_end: sti # Turn interrupts back on now
|
||||
#
|
||||
# Copy the BTX client to MEM_BTX_CLIENT
|
||||
#
|
||||
mov %cs,%ax
|
||||
mov %ax,%ds
|
||||
xor %ax,%ax
|
||||
mov %ax,%es
|
||||
mov $MEM_BTX_CLIENT,%di # Prepare to relocate
|
||||
mov $btx_client,%si # the simple btx client
|
||||
mov $(btx_client_end-btx_client),%cx # length of btx client
|
||||
rep # Relocate the
|
||||
movsb # simple BTX client
|
||||
#
|
||||
# Copy the boot[12] args to where the BTX client can see them
|
||||
#
|
||||
xor %ax,%ax
|
||||
mov %ax,%ds
|
||||
mov $MEM_ARG,%si # where the args are at now
|
||||
mov $MEM_ARG_BTX,%di # where the args are moving to
|
||||
mov $(MEM_ARG_SIZE/4),%cx # size of the arguments in longs
|
||||
rep # Relocate
|
||||
movsl # the words
|
||||
#
|
||||
# Save the entry point so the client can get to it later on
|
||||
#
|
||||
pop %eax # Restore saved entry point
|
||||
stosl # and add it to the end of
|
||||
# the arguments
|
||||
#
|
||||
# Now we just start up BTX and let it do the rest
|
||||
#
|
||||
mov $msg_jump,%si # Display the
|
||||
call putstr # jump message
|
||||
ljmp $0,$MEM_BTX_ENTRY # Jump to the BTX entry point
|
||||
|
||||
#
|
||||
# Lookup the file in the path at [SI] from the root directory.
|
||||
#
|
||||
# Trashes: All but BX
|
||||
# Returns: CF = 0 (success), BX = pointer to record
|
||||
# CF = 1 (not found)
|
||||
#
|
||||
lookup: mov $VD_ROOTDIR+MEM_VOLDESC,%bx # Root directory record
|
||||
push %bx
|
||||
push %si
|
||||
mov $msg_lookup,%si # Display lookup message
|
||||
call putstr
|
||||
pop %si
|
||||
push %si
|
||||
call putstr
|
||||
mov $msg_lookup2,%si
|
||||
call putstr
|
||||
pop %si
|
||||
pop %bx
|
||||
lookup_dir: lodsb # Get first char of path
|
||||
cmp $0,%al # Are we done?
|
||||
je lookup_done # Yes
|
||||
cmp $'/',%al # Skip path separator.
|
||||
je lookup_dir
|
||||
dec %si # Undo lodsb side effect
|
||||
call find_file # Lookup first path item
|
||||
jnc lookup_dir # Try next component
|
||||
mov $msg_lookupfail,%si # Not found message
|
||||
push %bx
|
||||
call putstr
|
||||
pop %bx
|
||||
stc # Set carry
|
||||
ret
|
||||
lookup_done: mov $msg_lookupok,%si # Success message
|
||||
push %bx
|
||||
call putstr
|
||||
pop %bx
|
||||
clc # Clear carry
|
||||
ret
|
||||
|
||||
#
|
||||
# Lookup file at [SI] in directory whose record is at [BX].
|
||||
#
|
||||
# Trashes: All but returns
|
||||
# Returns: CF = 0 (success), BX = pointer to record, SI = next path item
|
||||
# CF = 1 (not found), SI = preserved
|
||||
#
|
||||
find_file: mov %es:DIR_EXTENT(%bx),%eax # Load extent
|
||||
xor %edx,%edx
|
||||
mov %es:DIR_EA_LEN(%bx),%dl
|
||||
add %edx,%eax # Skip extended attributes
|
||||
mov %eax,rec_lba # Save LBA
|
||||
mov %es:DIR_SIZE(%bx),%eax # Save size
|
||||
mov %eax,rec_size
|
||||
xor %cl,%cl # Zero length
|
||||
push %si # Save
|
||||
ff.namelen: inc %cl # Update length
|
||||
lodsb # Read char
|
||||
cmp $0,%al # Nul?
|
||||
je ff.namedone # Yes
|
||||
cmp $'/',%al # Path separator?
|
||||
jnz ff.namelen # No, keep going
|
||||
ff.namedone: dec %cl # Adjust length and save
|
||||
mov %cl,name_len
|
||||
pop %si # Restore
|
||||
ff.load: mov rec_lba,%eax # Load LBA
|
||||
mov $MEM_DIR,%ebx # Address buffer
|
||||
mov $1,%dh # One sector
|
||||
call read # Read directory block
|
||||
incl rec_lba # Update LBA to next block
|
||||
ff.scan: mov %ebx,%edx # Check for EOF
|
||||
sub $MEM_DIR,%edx
|
||||
cmp %edx,rec_size
|
||||
ja ff.scan.1
|
||||
stc # EOF reached
|
||||
ret
|
||||
ff.scan.1: cmpb $0,%es:DIR_LEN(%bx) # Last record in block?
|
||||
je ff.nextblock
|
||||
push %si # Save
|
||||
movzbw %es:DIR_NAMELEN(%bx),%si # Find end of string
|
||||
ff.checkver: cmpb $'0',%es:DIR_NAME-1(%bx,%si) # Less than '0'?
|
||||
jb ff.checkver.1
|
||||
cmpb $'9',%es:DIR_NAME-1(%bx,%si) # Greater than '9'?
|
||||
ja ff.checkver.1
|
||||
dec %si # Next char
|
||||
jnz ff.checkver
|
||||
jmp ff.checklen # All numbers in name, so
|
||||
# no version
|
||||
ff.checkver.1: movzbw %es:DIR_NAMELEN(%bx),%cx
|
||||
cmp %cx,%si # Did we find any digits?
|
||||
je ff.checkdot # No
|
||||
cmpb $';',%es:DIR_NAME-1(%bx,%si) # Check for semicolon
|
||||
jne ff.checkver.2
|
||||
dec %si # Skip semicolon
|
||||
mov %si,%cx
|
||||
mov %cl,%es:DIR_NAMELEN(%bx) # Adjust length
|
||||
jmp ff.checkdot
|
||||
ff.checkver.2: mov %cx,%si # Restore %si to end of string
|
||||
ff.checkdot: cmpb $'.',%es:DIR_NAME-1(%bx,%si) # Trailing dot?
|
||||
jne ff.checklen # No
|
||||
decb %es:DIR_NAMELEN(%bx) # Adjust length
|
||||
ff.checklen: pop %si # Restore
|
||||
movzbw name_len,%cx # Load length of name
|
||||
cmp %cl,%es:DIR_NAMELEN(%bx) # Does length match?
|
||||
je ff.checkname # Yes, check name
|
||||
ff.nextrec: add %es:DIR_LEN(%bx),%bl # Next record
|
||||
adc $0,%bh
|
||||
jmp ff.scan
|
||||
ff.nextblock: subl $SECTOR_SIZE,rec_size # Adjust size
|
||||
jnc ff.load # If subtract ok, keep going
|
||||
ret # End of file, so not found
|
||||
ff.checkname: lea DIR_NAME(%bx),%di # Address name in record
|
||||
push %si # Save
|
||||
repe cmpsb # Compare name
|
||||
je ff.match # We have a winner!
|
||||
pop %si # Restore
|
||||
jmp ff.nextrec # Keep looking.
|
||||
ff.match: add $2,%sp # Discard saved %si
|
||||
clc # Clear carry
|
||||
ret
|
||||
|
||||
#
|
||||
# Load DH sectors starting at LBA EAX into [EBX].
|
||||
#
|
||||
# Trashes: EAX
|
||||
#
|
||||
read: push %es # Save
|
||||
push %bp
|
||||
push %dx
|
||||
push %cx
|
||||
push %ebx
|
||||
mov %bx,%bp # Set destination address
|
||||
and $0x000f,%bp
|
||||
shr $4,%ebx
|
||||
mov %bx,%es
|
||||
xor %bx,%bx # Set read bytes
|
||||
mov %dh,%bl
|
||||
shl $SECTOR_SHIFT,%bx # 2048 bytes/sec
|
||||
mov %ax,%cx # Set LBA
|
||||
shr $16,%eax
|
||||
mov %ax,%dx
|
||||
read.retry: mov $0x06,%ah # BIOS device read
|
||||
mov drive,%al
|
||||
and $0x7f,%al
|
||||
call twiddle # Entertain the user
|
||||
int $0x1b # Call BIOS
|
||||
jc read.fail # Worked?
|
||||
pop %ebx # Restore
|
||||
pop %cx
|
||||
pop %dx
|
||||
pop %bp
|
||||
pop %es
|
||||
ret # Return
|
||||
read.fail: cmp $ERROR_TIMEOUT,%ah # Timeout?
|
||||
je read.retry # Yes, Retry.
|
||||
read.error: mov %ah,%al # Save error
|
||||
mov $hex_error,%di # Format it
|
||||
call hex8 # as hex
|
||||
mov $msg_badread,%si # Display Read error message
|
||||
jmp error
|
||||
|
||||
#
|
||||
# Output the "twiddle"
|
||||
#
|
||||
twiddle: push %ax # Save
|
||||
push %bx # Save
|
||||
mov twiddle_index,%al # Load index
|
||||
mov $twiddle_chars,%bx # Address table
|
||||
inc %al # Next
|
||||
and $3,%al # char
|
||||
mov %al,twiddle_index # Save index for next call
|
||||
xlat # Get char
|
||||
call putc # Output it
|
||||
pop %bx # Restore
|
||||
pop %ax # Restore
|
||||
ret
|
||||
|
||||
#
|
||||
# Convert AL to hex, saving the result to [EDI].
|
||||
#
|
||||
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
|
||||
mov %al,(%di) # Save char
|
||||
inc %di
|
||||
ret # (Recursive)
|
||||
|
||||
#
|
||||
# BTX client to start btxldr
|
||||
#
|
||||
.code32
|
||||
btx_client: mov $(MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE-4), %esi
|
||||
# %ds:(%esi) -> end
|
||||
# of boot[12] args
|
||||
mov $(MEM_ARG_SIZE/4),%ecx # Number of words to push
|
||||
std # Go backwards
|
||||
push_arg: lodsl # Read argument
|
||||
push %eax # Push it onto the stack
|
||||
loop push_arg # Push all of the arguments
|
||||
cld # In case anyone depends on this
|
||||
pushl MEM_ARG_BTX-MEM_BTX_CLIENT+MEM_ARG_SIZE # Entry point of
|
||||
# the loader
|
||||
push %eax # Emulate a near call
|
||||
mov $0x1,%eax # 'exec' system call
|
||||
int $INT_SYS # BTX system call
|
||||
btx_client_end:
|
||||
.code16
|
||||
|
||||
.p2align 4
|
||||
#
|
||||
# Global descriptor table.
|
||||
#
|
||||
gdt: .word 0x0,0x0,0x0,0x0 # Null entry
|
||||
.word 0xffff,0x0000,0x9200,0x00cf # SEL_SDATA
|
||||
.word 0xffff,0x0000,0x9200,0x0000 # SEL_RDATA
|
||||
.word 0xffff,LOAD_SEG<<4,0x9a00,0x00cf # SEL_SCODE (32-bit)
|
||||
.word 0xffff,LOAD_SEG<<4,0x9a00,0x008f # SEL_SCODE16 (16-bit)
|
||||
gdt.1:
|
||||
#
|
||||
# Pseudo-descriptors.
|
||||
#
|
||||
gdtdesc: .word gdt.1-gdt-1 # Limit
|
||||
.long LOAD_SEG<<4 + gdt # Base
|
||||
|
||||
#
|
||||
# BOOT device
|
||||
#
|
||||
drive: .byte 0
|
||||
cylinder: .word 0
|
||||
|
||||
#
|
||||
# State for searching dir
|
||||
#
|
||||
rec_lba: .long 0x0 # LBA (adjusted for EA)
|
||||
rec_size: .long 0x0 # File size
|
||||
name_len: .byte 0x0 # Length of current name
|
||||
|
||||
cursor: .word 0
|
||||
twiddle_index: .byte 0x0
|
||||
|
||||
msg_welcome: .asciz "CD Loader 1.2\r\n\n"
|
||||
msg_bootinfo: .asciz "Building the boot loader arguments\r\n"
|
||||
msg_relocate: .asciz "Relocating the loader and the BTX\r\n"
|
||||
msg_jump: .asciz "Starting the BTX loader\r\n"
|
||||
msg_badread: .ascii "Read Error: 0x"
|
||||
hex_error: .asciz "00\r\n"
|
||||
msg_novd: .asciz "Could not find Primary Volume Descriptor\r\n"
|
||||
msg_lookup: .asciz "Looking up "
|
||||
msg_lookup2: .asciz "... "
|
||||
msg_lookupok: .asciz "Found\r\n"
|
||||
msg_lookupfail: .asciz "File not found\r\n"
|
||||
msg_load2big: .asciz "File too big\r\n"
|
||||
msg_failed: .asciz "Boot failed\r\n"
|
||||
twiddle_chars: .ascii "|/-\\"
|
||||
loader_paths: .asciz "/BOOT.PC98/LOADER"
|
||||
.asciz "/boot.pc98/loader"
|
||||
.asciz "/BOOT/LOADER"
|
||||
.asciz "/boot/loader"
|
||||
.byte 0
|
||||
|
||||
/* Boot signature */
|
||||
|
||||
.org SIG2_OFF,0x90
|
||||
|
||||
.word 0xaa55 # Magic number
|
20
sys/boot/pc98/kgzldr/Makefile
Normal file
20
sys/boot/pc98/kgzldr/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= kgzldr.o
|
||||
STRIP=
|
||||
BINMODE=${LIBMODE}
|
||||
BINDIR= ${LIBDIR}
|
||||
MAN=
|
||||
|
||||
SRCS= start.s boot.c inflate.c lib.c crt.s sio.s
|
||||
CFLAGS= -Os
|
||||
CFLAGS+=-DKZIP
|
||||
NO_SHARED=
|
||||
LDFLAGS=-Wl,-r
|
||||
.PATH: ${.CURDIR}/../../../kern
|
||||
.PATH: ${.CURDIR}/../../i386/kgzldr
|
||||
|
||||
BOOT_COMCONSOLE_PORT?= 0x238
|
||||
AFLAGS+=--defsym SIO_PRT=${BOOT_COMCONSOLE_PORT}
|
||||
|
||||
.include <bsd.prog.mk>
|
89
sys/boot/pc98/kgzldr/crt.s
Normal file
89
sys/boot/pc98/kgzldr/crt.s
Normal file
@ -0,0 +1,89 @@
|
||||
#
|
||||
# Copyright (c) 1999 Global Technology Associates, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE 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: btx.s 1.10 1999/02/25 16:27:41 rnordier
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# Screen defaults and assumptions.
|
||||
|
||||
.set SCR_MAT,0xe1 # Mode/attribute
|
||||
.set SCR_COL,0x50 # Columns per row
|
||||
.set SCR_ROW,0x19 # Rows per screen
|
||||
|
||||
# BIOS Data Area locations.
|
||||
|
||||
.set BDA_POS,0x53e # Cursor position
|
||||
|
||||
.globl crt_putchr
|
||||
|
||||
# void crt_putchr(int c)
|
||||
|
||||
crt_putchr: movb 0x4(%esp,1),%al # Get character
|
||||
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
|
||||
movl $0xa0000,%edi
|
||||
crt_putchr.1: cmpb $0xa,%al # New line?
|
||||
je crt_putchr.2 # Yes
|
||||
movw %dx,%cx
|
||||
movb %al,(%edi,%ecx,1) # Write char
|
||||
addl $0x2000,%ecx
|
||||
movb %ah,(%edi,%ecx,1) # Write attr
|
||||
addw $0x02,%dx
|
||||
jmp crt_putchr.3
|
||||
crt_putchr.2: movw %dx,%ax
|
||||
movb $SCR_COL*2,%dl
|
||||
div %dl
|
||||
incb %al
|
||||
mul %dl
|
||||
movw %ax,%dx
|
||||
crt_putchr.3: cmpw $SCR_ROW*SCR_COL*2,%dx
|
||||
jb crt_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
|
||||
xorb %ah,%ah
|
||||
movb $SCR_COL,%cl # Columns to clear
|
||||
rep # Clear
|
||||
stosw # line
|
||||
movw $(SCR_ROW-1)*SCR_COL*2,%dx
|
||||
crt_putchr.4: movw %dx,(%ebx) # Update position
|
||||
shrw $1,%dx
|
||||
crt_putchr.5: inb $0x60,%al # Move cursor
|
||||
testb $0x04,%al
|
||||
jz crt_putchr.5
|
||||
movb $0x49,%al
|
||||
outb %al,$0x62
|
||||
movb %dl,%al
|
||||
outb %al,$0x60
|
||||
movb %dh,%al
|
||||
outb %al,$0x60
|
||||
popa # Restore
|
||||
ret # To caller
|
51
sys/boot/pc98/libpc98/Makefile
Normal file
51
sys/boot/pc98/libpc98/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
LIB= pc98
|
||||
INTERNALLIB=
|
||||
|
||||
.PATH: ${.CURDIR}/../../i386/libi386
|
||||
|
||||
SRCS= bioscd.c biosdisk.c biosmem.c biospnp.c \
|
||||
biospci.c biossmap.c bootinfo.c bootinfo32.c \
|
||||
comconsole.c devicename.c elf32_freebsd.c \
|
||||
i386_copy.c i386_module.c nullconsole.c pc98_sys.c pxe.c pxetramp.s \
|
||||
time.c vidconsole.c
|
||||
.PATH: ${.CURDIR}/../../zfs
|
||||
SRCS+= devicename_stubs.c
|
||||
|
||||
# Enable PXE TFTP or NFS support, not both.
|
||||
.if defined(LOADER_TFTP_SUPPORT)
|
||||
CFLAGS+= -DLOADER_TFTP_SUPPORT
|
||||
.else
|
||||
CFLAGS+= -DLOADER_NFS_SUPPORT
|
||||
.endif
|
||||
|
||||
BOOT_COMCONSOLE_PORT?= 0x238
|
||||
CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT}
|
||||
|
||||
BOOT_COMCONSOLE_SPEED?= 9600
|
||||
CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
|
||||
|
||||
.ifdef(BOOT_BIOSDISK_DEBUG)
|
||||
# Make the disk code more talkative
|
||||
CFLAGS+= -DDISK_DEBUG
|
||||
.endif
|
||||
|
||||
# Include simple terminal emulation (cons25-compatible)
|
||||
CFLAGS+= -DTERM_EMU
|
||||
|
||||
# XXX: make alloca() useable
|
||||
CFLAGS+= -Dalloca=__builtin_alloca
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 \
|
||||
-I${.CURDIR}/../../common \
|
||||
-I${.CURDIR}/../btx/lib \
|
||||
-I${.CURDIR}/../../i386/libi386 \
|
||||
-I${.CURDIR}/../../.. -I.
|
||||
# the location of libstand
|
||||
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
|
||||
|
||||
# Handle FreeBSD specific %b and %D printf format specifiers
|
||||
CFLAGS+= ${FORMAT_EXTENSIONS}
|
||||
|
||||
.include <bsd.lib.mk>
|
420
sys/boot/pc98/libpc98/bioscd.c
Normal file
420
sys/boot/pc98/libpc98/bioscd.c
Normal file
@ -0,0 +1,420 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
|
||||
* Copyright (c) 2001 John H. Baldwin <jhb@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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* BIOS CD device handling for CD's that have been booted off of via no
|
||||
* emulation booting as defined in the El Torito standard.
|
||||
*
|
||||
* Ideas and algorithms from:
|
||||
*
|
||||
* - FreeBSD libi386/biosdisk.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <machine/bootinfo.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <bootstrap.h>
|
||||
#include <btxv86.h>
|
||||
#include "libi386.h"
|
||||
|
||||
#define BIOSCD_SECSIZE 2048
|
||||
#define BUFSIZE (1 * BIOSCD_SECSIZE)
|
||||
#define MAXBCDEV 1
|
||||
|
||||
/* Major numbers for devices we frontend for. */
|
||||
#define ACDMAJOR 117
|
||||
#define CDMAJOR 15
|
||||
|
||||
#ifdef DISK_DEBUG
|
||||
# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
|
||||
#else
|
||||
# define DEBUG(fmt, args...)
|
||||
#endif
|
||||
|
||||
struct specification_packet {
|
||||
u_char sp_size;
|
||||
u_char sp_bootmedia;
|
||||
u_char sp_drive;
|
||||
u_char sp_controller;
|
||||
u_int sp_lba;
|
||||
u_short sp_devicespec;
|
||||
u_short sp_buffersegment;
|
||||
u_short sp_loadsegment;
|
||||
u_short sp_sectorcount;
|
||||
u_short sp_cylsec;
|
||||
u_char sp_head;
|
||||
};
|
||||
|
||||
/*
|
||||
* List of BIOS devices, translation from disk unit number to
|
||||
* BIOS unit number.
|
||||
*/
|
||||
static struct bcinfo {
|
||||
int bc_unit; /* BIOS unit number */
|
||||
struct specification_packet bc_sp;
|
||||
int bc_open; /* reference counter */
|
||||
void *bc_bcache; /* buffer cache data */
|
||||
} bcinfo [MAXBCDEV];
|
||||
static int nbcinfo = 0;
|
||||
|
||||
#define BC(dev) (bcinfo[(dev)->d_unit])
|
||||
|
||||
static int bc_read(int unit, daddr_t dblk, int blks, caddr_t dest);
|
||||
static int bc_init(void);
|
||||
static int bc_strategy(void *devdata, int flag, daddr_t dblk,
|
||||
size_t size, char *buf, size_t *rsize);
|
||||
static int bc_realstrategy(void *devdata, int flag, daddr_t dblk,
|
||||
size_t size, char *buf, size_t *rsize);
|
||||
static int bc_open(struct open_file *f, ...);
|
||||
static int bc_close(struct open_file *f);
|
||||
static int bc_print(int verbose);
|
||||
|
||||
struct devsw bioscd = {
|
||||
"cd",
|
||||
DEVT_CD,
|
||||
bc_init,
|
||||
bc_strategy,
|
||||
bc_open,
|
||||
bc_close,
|
||||
noioctl,
|
||||
bc_print,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Translate between BIOS device numbers and our private unit numbers.
|
||||
*/
|
||||
int
|
||||
bc_bios2unit(int biosdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUG("looking for bios device 0x%x", biosdev);
|
||||
for (i = 0; i < nbcinfo; i++) {
|
||||
DEBUG("bc unit %d is BIOS device 0x%x", i, bcinfo[i].bc_unit);
|
||||
if (bcinfo[i].bc_unit == biosdev)
|
||||
return(i);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int
|
||||
bc_unit2bios(int unit)
|
||||
{
|
||||
if ((unit >= 0) && (unit < nbcinfo))
|
||||
return(bcinfo[unit].bc_unit);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't quiz, we have to be told what device to use, so this functoin
|
||||
* doesn't do anything. Instead, the loader calls bc_add() with the BIOS
|
||||
* device number to add.
|
||||
*/
|
||||
static int
|
||||
bc_init(void)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
bc_add(int biosdev)
|
||||
{
|
||||
|
||||
if (nbcinfo >= MAXBCDEV)
|
||||
return (-1);
|
||||
bcinfo[nbcinfo].bc_unit = biosdev;
|
||||
|
||||
/* SCSI CD-ROM only */
|
||||
if ((biosdev & 0xf0) != 0xa0)
|
||||
return (-1);
|
||||
if ((((uint32_t *)PTOV(0xA1460))[biosdev & 0x0f] & 0x1f) != 5)
|
||||
return (-1);
|
||||
|
||||
printf("BIOS CD is cd%d\n", nbcinfo);
|
||||
nbcinfo++;
|
||||
bcache_add_dev(nbcinfo); /* register cd device in bcache */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print information about disks
|
||||
*/
|
||||
static int
|
||||
bc_print(int verbose)
|
||||
{
|
||||
char line[80];
|
||||
int i, ret = 0;
|
||||
|
||||
if (nbcinfo == 0)
|
||||
return (0);
|
||||
|
||||
printf("%s devices:", bioscd.dv_name);
|
||||
if ((ret = pager_output("\n")) != 0)
|
||||
return (ret);
|
||||
|
||||
for (i = 0; i < nbcinfo; i++) {
|
||||
sprintf(line, " cd%d: Device 0x%x\n", i,
|
||||
bcinfo[i].bc_sp.sp_devicespec);
|
||||
if ((ret = pager_output(line)) != 0)
|
||||
break;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to open the disk described by (dev) for use by (f).
|
||||
*/
|
||||
static int
|
||||
bc_open(struct open_file *f, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct i386_devdesc *dev;
|
||||
|
||||
va_start(ap, f);
|
||||
dev = va_arg(ap, struct i386_devdesc *);
|
||||
va_end(ap);
|
||||
if (dev->d_unit >= nbcinfo) {
|
||||
DEBUG("attempt to open nonexistent disk");
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
BC(dev).bc_open++;
|
||||
if (BC(dev).bc_bcache == NULL)
|
||||
BC(dev).bc_bcache = bcache_allocate();
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
bc_close(struct open_file *f)
|
||||
{
|
||||
struct i386_devdesc *dev;
|
||||
|
||||
dev = (struct i386_devdesc *)f->f_devdata;
|
||||
BC(dev).bc_open--;
|
||||
if (BC(dev).bc_open == 0) {
|
||||
bcache_free(BC(dev).bc_bcache);
|
||||
BC(dev).bc_bcache = NULL;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
bc_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
|
||||
char *buf, size_t *rsize)
|
||||
{
|
||||
struct bcache_devdata bcd;
|
||||
struct i386_devdesc *dev;
|
||||
|
||||
dev = (struct i386_devdesc *)devdata;
|
||||
bcd.dv_strategy = bc_realstrategy;
|
||||
bcd.dv_devdata = devdata;
|
||||
bcd.dv_cache = BC(dev).bc_bcache;
|
||||
|
||||
return (bcache_strategy(&bcd, rw, dblk, size, buf, rsize));
|
||||
}
|
||||
|
||||
static int
|
||||
bc_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
|
||||
char *buf, size_t *rsize)
|
||||
{
|
||||
struct i386_devdesc *dev;
|
||||
int unit;
|
||||
int blks;
|
||||
#ifdef BD_SUPPORT_FRAGS
|
||||
char fragbuf[BIOSCD_SECSIZE];
|
||||
size_t fragsize;
|
||||
|
||||
fragsize = size % BIOSCD_SECSIZE;
|
||||
#else
|
||||
if (size % BIOSCD_SECSIZE)
|
||||
return (EINVAL);
|
||||
#endif
|
||||
|
||||
if (rw != F_READ)
|
||||
return(EROFS);
|
||||
dev = (struct i386_devdesc *)devdata;
|
||||
unit = dev->d_unit;
|
||||
blks = size / BIOSCD_SECSIZE;
|
||||
if (dblk % (BIOSCD_SECSIZE / DEV_BSIZE) != 0)
|
||||
return (EINVAL);
|
||||
dblk /= (BIOSCD_SECSIZE / DEV_BSIZE);
|
||||
DEBUG("read %d from %lld to %p", blks, dblk, buf);
|
||||
|
||||
if (rsize)
|
||||
*rsize = 0;
|
||||
if (blks && bc_read(unit, dblk, blks, buf)) {
|
||||
DEBUG("read error");
|
||||
return (EIO);
|
||||
}
|
||||
#ifdef BD_SUPPORT_FRAGS
|
||||
DEBUG("frag read %d from %lld+%d to %p",
|
||||
fragsize, dblk, blks, buf + (blks * BIOSCD_SECSIZE));
|
||||
if (fragsize && bc_read(unit, dblk + blks, 1, fragbuf)) {
|
||||
DEBUG("frag read error");
|
||||
return(EIO);
|
||||
}
|
||||
bcopy(fragbuf, buf + (blks * BIOSCD_SECSIZE), fragsize);
|
||||
#endif
|
||||
if (rsize)
|
||||
*rsize = size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Max number of sectors to bounce-buffer at a time. */
|
||||
#define CD_BOUNCEBUF 8
|
||||
|
||||
static int
|
||||
bc_read(int unit, daddr_t dblk, int blks, caddr_t dest)
|
||||
{
|
||||
u_int maxfer, resid, result, retry, x;
|
||||
caddr_t bbuf, p, xp;
|
||||
int biosdev;
|
||||
#ifdef DISK_DEBUG
|
||||
int error;
|
||||
#endif
|
||||
|
||||
/* Just in case some idiot actually tries to read -1 blocks... */
|
||||
if (blks < 0)
|
||||
return (-1);
|
||||
|
||||
/* If nothing to do, just return succcess. */
|
||||
if (blks == 0)
|
||||
return (0);
|
||||
|
||||
/* Decide whether we have to bounce */
|
||||
if (VTOP(dest) >> 20 != 0) {
|
||||
/*
|
||||
* The destination buffer is above first 1MB of
|
||||
* physical memory so we have to arrange a suitable
|
||||
* bounce buffer.
|
||||
*/
|
||||
x = min(CD_BOUNCEBUF, (unsigned)blks);
|
||||
bbuf = alloca(x * BIOSCD_SECSIZE);
|
||||
maxfer = x;
|
||||
} else {
|
||||
bbuf = NULL;
|
||||
maxfer = 0;
|
||||
}
|
||||
|
||||
biosdev = bc_unit2bios(unit);
|
||||
resid = blks;
|
||||
p = dest;
|
||||
|
||||
while (resid > 0) {
|
||||
if (bbuf)
|
||||
xp = bbuf;
|
||||
else
|
||||
xp = p;
|
||||
x = resid;
|
||||
if (maxfer > 0)
|
||||
x = min(x, maxfer);
|
||||
|
||||
/*
|
||||
* Loop retrying the operation a couple of times. The BIOS
|
||||
* may also retry.
|
||||
*/
|
||||
for (retry = 0; retry < 3; retry++) {
|
||||
/* If retrying, reset the drive */
|
||||
if (retry > 0) {
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.addr = 0x1b;
|
||||
v86.eax = 0x0300 | biosdev;
|
||||
v86int();
|
||||
}
|
||||
|
||||
v86.ctl = V86_FLAGS;
|
||||
v86.addr = 0x1b;
|
||||
v86.eax = 0x0600 | (biosdev & 0x7f);
|
||||
v86.ebx = x * BIOSCD_SECSIZE;
|
||||
v86.ecx = dblk & 0xffff;
|
||||
v86.edx = (dblk >> 16) & 0xffff;
|
||||
v86.ebp = VTOPOFF(xp);
|
||||
v86.es = VTOPSEG(xp);
|
||||
v86int();
|
||||
result = V86_CY(v86.efl);
|
||||
if (result == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DISK_DEBUG
|
||||
error = (v86.eax >> 8) & 0xff;
|
||||
#endif
|
||||
DEBUG("%d sectors from %lld to %p (0x%x) %s", x, dblk, p,
|
||||
VTOP(p), result ? "failed" : "ok");
|
||||
DEBUG("unit %d status 0x%x", unit, error);
|
||||
if (bbuf != NULL)
|
||||
bcopy(bbuf, p, x * BIOSCD_SECSIZE);
|
||||
p += (x * BIOSCD_SECSIZE);
|
||||
dblk += x;
|
||||
resid -= x;
|
||||
}
|
||||
|
||||
/* hexdump(dest, (blks * BIOSCD_SECSIZE)); */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a suitable dev_t value for (dev).
|
||||
*/
|
||||
int
|
||||
bc_getdev(struct i386_devdesc *dev)
|
||||
{
|
||||
int biosdev, unit, device;
|
||||
int major;
|
||||
int rootdev;
|
||||
|
||||
unit = dev->d_unit;
|
||||
biosdev = bc_unit2bios(unit);
|
||||
DEBUG("unit %d BIOS device %d", unit, biosdev);
|
||||
if (biosdev == -1) /* not a BIOS device */
|
||||
return(-1);
|
||||
|
||||
device = biosdev & 0xf0;
|
||||
if (device == 0x80)
|
||||
major = ACDMAJOR;
|
||||
else if (device == 0xa0)
|
||||
major = CDMAJOR;
|
||||
else
|
||||
return (-1);
|
||||
|
||||
unit = 0; /* XXX */
|
||||
|
||||
/* XXX: Assume partition 'a'. */
|
||||
rootdev = MAKEBOOTDEV(major, 0, unit, 0);
|
||||
DEBUG("dev is 0x%x\n", rootdev);
|
||||
return(rootdev);
|
||||
}
|
1120
sys/boot/pc98/libpc98/biosdisk.c
Normal file
1120
sys/boot/pc98/libpc98/biosdisk.c
Normal file
File diff suppressed because it is too large
Load Diff
64
sys/boot/pc98/libpc98/biosmem.c
Normal file
64
sys/boot/pc98/libpc98/biosmem.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Obtain memory configuration information from the BIOS
|
||||
*/
|
||||
#include <stand.h>
|
||||
#include "libi386.h"
|
||||
#include "btxv86.h"
|
||||
|
||||
vm_offset_t memtop, memtop_copyin, high_heap_base;
|
||||
uint32_t bios_basemem, bios_extmem, high_heap_size;
|
||||
|
||||
/*
|
||||
* The minimum amount of memory to reserve in bios_extmem for the heap.
|
||||
*/
|
||||
#define HEAP_MIN (64 * 1024 * 1024)
|
||||
|
||||
void
|
||||
bios_getmem(void)
|
||||
{
|
||||
|
||||
bios_basemem = ((*(u_char *)PTOV(0xA1501) & 0x07) + 1) * 128 * 1024;
|
||||
bios_extmem = *(u_char *)PTOV(0xA1401) * 128 * 1024 +
|
||||
*(u_int16_t *)PTOV(0xA1594) * 1024 * 1024;
|
||||
|
||||
/* Set memtop to actual top of memory */
|
||||
memtop = memtop_copyin = 0x100000 + bios_extmem;
|
||||
|
||||
/*
|
||||
* If we have extended memory, use the last 3MB of 'extended' memory
|
||||
* as a high heap candidate.
|
||||
*/
|
||||
if (bios_extmem >= HEAP_MIN) {
|
||||
high_heap_size = HEAP_MIN;
|
||||
high_heap_base = memtop - HEAP_MIN;
|
||||
}
|
||||
}
|
38
sys/boot/pc98/libpc98/biossmap.c
Normal file
38
sys/boot/pc98/libpc98/biossmap.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 TAKAHASHI Yoshihiro <nyan@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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <sys/param.h>
|
||||
#include "libi386.h"
|
||||
|
||||
void
|
||||
bios_addsmapdata(struct preloaded_file *kfp)
|
||||
{
|
||||
|
||||
}
|
367
sys/boot/pc98/libpc98/comconsole.c
Normal file
367
sys/boot/pc98/libpc98/comconsole.c
Normal file
@ -0,0 +1,367 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <bootstrap.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <dev/ic/ns16550.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include "libi386.h"
|
||||
|
||||
#define COMC_FMT 0x3 /* 8N1 */
|
||||
#define COMC_TXWAIT 0x40000 /* transmit timeout */
|
||||
#define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */
|
||||
#define COMC_DIV2BPS(x) (115200 / (x)) /* DLAB divisor to speed */
|
||||
|
||||
#ifndef COMPORT
|
||||
#define COMPORT 0x238
|
||||
#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_getspeed(void);
|
||||
static int comc_ischar(void);
|
||||
static int comc_parseint(const char *string);
|
||||
static uint32_t comc_parse_pcidev(const char *string);
|
||||
static int comc_pcidev_set(struct env_var *ev, int flags,
|
||||
const void *value);
|
||||
static int comc_pcidev_handle(uint32_t locator);
|
||||
static int comc_port_set(struct env_var *ev, int flags,
|
||||
const void *value);
|
||||
static void comc_setup(int speed, int port);
|
||||
static int comc_speed_set(struct env_var *ev, int flags,
|
||||
const void *value);
|
||||
|
||||
static int comc_curspeed;
|
||||
static int comc_port = COMPORT;
|
||||
static uint32_t comc_locator;
|
||||
|
||||
struct console comconsole = {
|
||||
"comconsole",
|
||||
"serial port",
|
||||
0,
|
||||
comc_probe,
|
||||
comc_init,
|
||||
comc_putchar,
|
||||
comc_getchar,
|
||||
comc_ischar
|
||||
};
|
||||
|
||||
static void
|
||||
comc_probe(struct console *cp)
|
||||
{
|
||||
char intbuf[16];
|
||||
char *cons, *env;
|
||||
int speed, port;
|
||||
uint32_t locator;
|
||||
|
||||
if (comc_curspeed == 0) {
|
||||
comc_curspeed = COMSPEED;
|
||||
/*
|
||||
* Assume that the speed was set by an earlier boot loader if
|
||||
* comconsole is already the preferred console.
|
||||
*/
|
||||
cons = getenv("console");
|
||||
if ((cons != NULL && strcmp(cons, comconsole.c_name) == 0) ||
|
||||
getenv("boot_multicons") != NULL) {
|
||||
comc_curspeed = comc_getspeed();
|
||||
}
|
||||
|
||||
env = getenv("comconsole_speed");
|
||||
if (env != NULL) {
|
||||
speed = comc_parseint(env);
|
||||
if (speed > 0)
|
||||
comc_curspeed = speed;
|
||||
}
|
||||
|
||||
sprintf(intbuf, "%d", comc_curspeed);
|
||||
unsetenv("comconsole_speed");
|
||||
env_setenv("comconsole_speed", EV_VOLATILE, intbuf, comc_speed_set,
|
||||
env_nounset);
|
||||
|
||||
env = getenv("comconsole_port");
|
||||
if (env != NULL) {
|
||||
port = comc_parseint(env);
|
||||
if (port > 0)
|
||||
comc_port = port;
|
||||
}
|
||||
|
||||
sprintf(intbuf, "%d", comc_port);
|
||||
unsetenv("comconsole_port");
|
||||
env_setenv("comconsole_port", EV_VOLATILE, intbuf, comc_port_set,
|
||||
env_nounset);
|
||||
|
||||
env = getenv("comconsole_pcidev");
|
||||
if (env != NULL) {
|
||||
locator = comc_parse_pcidev(env);
|
||||
if (locator != 0)
|
||||
comc_pcidev_handle(locator);
|
||||
}
|
||||
|
||||
unsetenv("comconsole_pcidev");
|
||||
env_setenv("comconsole_pcidev", EV_VOLATILE, env, comc_pcidev_set,
|
||||
env_nounset);
|
||||
}
|
||||
comc_setup(comc_curspeed, comc_port);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_init(int arg)
|
||||
{
|
||||
|
||||
comc_setup(comc_curspeed, comc_port);
|
||||
|
||||
if ((comconsole.c_flags & (C_PRESENTIN | C_PRESENTOUT)) ==
|
||||
(C_PRESENTIN | C_PRESENTOUT))
|
||||
return (CMD_OK);
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
comc_putchar(int c)
|
||||
{
|
||||
int wait;
|
||||
|
||||
for (wait = COMC_TXWAIT; wait > 0; wait--)
|
||||
if (inb(comc_port + com_lsr) & LSR_TXRDY) {
|
||||
outb(comc_port + com_data, (u_char)c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
comc_getchar(void)
|
||||
{
|
||||
return (comc_ischar() ? inb(comc_port + com_data) : -1);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_ischar(void)
|
||||
{
|
||||
return (inb(comc_port + com_lsr) & LSR_RXRDY);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_speed_set(struct env_var *ev, int flags, const void *value)
|
||||
{
|
||||
int speed;
|
||||
|
||||
if (value == NULL || (speed = comc_parseint(value)) <= 0) {
|
||||
printf("Invalid speed\n");
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
if (comc_curspeed != speed)
|
||||
comc_setup(speed, comc_port);
|
||||
|
||||
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
|
||||
|
||||
return (CMD_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_port_set(struct env_var *ev, int flags, const void *value)
|
||||
{
|
||||
int port;
|
||||
|
||||
if (value == NULL || (port = comc_parseint(value)) <= 0) {
|
||||
printf("Invalid port\n");
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
if (comc_port != port)
|
||||
comc_setup(comc_curspeed, port);
|
||||
|
||||
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
|
||||
|
||||
return (CMD_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Input: bus:dev:func[:bar]. If bar is not specified, it is 0x10.
|
||||
* Output: bar[24:16] bus[15:8] dev[7:3] func[2:0]
|
||||
*/
|
||||
static uint32_t
|
||||
comc_parse_pcidev(const char *string)
|
||||
{
|
||||
char *p, *p1;
|
||||
uint8_t bus, dev, func, bar;
|
||||
uint32_t locator;
|
||||
int pres;
|
||||
|
||||
pres = strtol(string, &p, 0);
|
||||
if (p == string || *p != ':' || pres < 0 )
|
||||
return (0);
|
||||
bus = pres;
|
||||
p1 = ++p;
|
||||
|
||||
pres = strtol(p1, &p, 0);
|
||||
if (p == string || *p != ':' || pres < 0 )
|
||||
return (0);
|
||||
dev = pres;
|
||||
p1 = ++p;
|
||||
|
||||
pres = strtol(p1, &p, 0);
|
||||
if (p == string || (*p != ':' && *p != '\0') || pres < 0 )
|
||||
return (0);
|
||||
func = pres;
|
||||
|
||||
if (*p == ':') {
|
||||
p1 = ++p;
|
||||
pres = strtol(p1, &p, 0);
|
||||
if (p == string || *p != '\0' || pres <= 0 )
|
||||
return (0);
|
||||
bar = pres;
|
||||
} else
|
||||
bar = 0x10;
|
||||
|
||||
locator = (bar << 16) | biospci_locator(bus, dev, func);
|
||||
return (locator);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_pcidev_handle(uint32_t locator)
|
||||
{
|
||||
char intbuf[64];
|
||||
uint32_t port;
|
||||
|
||||
if (biospci_read_config(locator & 0xffff,
|
||||
(locator & 0xff0000) >> 16, 2, &port) == -1) {
|
||||
printf("Cannot read bar at 0x%x\n", locator);
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
if (!PCI_BAR_IO(port)) {
|
||||
printf("Memory bar at 0x%x\n", locator);
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
port &= PCIM_BAR_IO_BASE;
|
||||
|
||||
sprintf(intbuf, "%d", port);
|
||||
unsetenv("comconsole_port");
|
||||
env_setenv("comconsole_port", EV_VOLATILE, intbuf,
|
||||
comc_port_set, env_nounset);
|
||||
|
||||
comc_setup(comc_curspeed, port);
|
||||
comc_locator = locator;
|
||||
|
||||
return (CMD_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_pcidev_set(struct env_var *ev, int flags, const void *value)
|
||||
{
|
||||
uint32_t locator;
|
||||
int error;
|
||||
|
||||
if (value == NULL || (locator = comc_parse_pcidev(value)) <= 0) {
|
||||
printf("Invalid pcidev\n");
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
|
||||
comc_locator != locator) {
|
||||
error = comc_pcidev_handle(locator);
|
||||
if (error != CMD_OK)
|
||||
return (error);
|
||||
}
|
||||
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
|
||||
return (CMD_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
comc_setup(int speed, int port)
|
||||
{
|
||||
static int TRY_COUNT = 1000000;
|
||||
char intbuf[64];
|
||||
int tries;
|
||||
|
||||
unsetenv("hw.uart.console");
|
||||
comc_curspeed = speed;
|
||||
comc_port = port;
|
||||
if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) == 0)
|
||||
return;
|
||||
|
||||
outb(comc_port + com_cfcr, CFCR_DLAB | COMC_FMT);
|
||||
outb(comc_port + com_dlbl, COMC_BPS(speed) & 0xff);
|
||||
outb(comc_port + com_dlbh, COMC_BPS(speed) >> 8);
|
||||
outb(comc_port + com_cfcr, COMC_FMT);
|
||||
outb(comc_port + com_mcr, MCR_RTS | MCR_DTR);
|
||||
|
||||
tries = 0;
|
||||
do
|
||||
inb(comc_port + com_data);
|
||||
while (inb(comc_port + com_lsr) & LSR_RXRDY && ++tries < TRY_COUNT);
|
||||
|
||||
if (tries < TRY_COUNT) {
|
||||
comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT);
|
||||
sprintf(intbuf, "io:%d,br:%d", comc_port, comc_curspeed);
|
||||
env_setenv("hw.uart.console", EV_VOLATILE, intbuf, NULL, NULL);
|
||||
} else
|
||||
comconsole.c_flags &= ~(C_PRESENTIN | C_PRESENTOUT);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_parseint(const char *speedstr)
|
||||
{
|
||||
char *p;
|
||||
int speed;
|
||||
|
||||
speed = strtol(speedstr, &p, 0);
|
||||
if (p == speedstr || *p != '\0' || speed <= 0)
|
||||
return (-1);
|
||||
|
||||
return (speed);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_getspeed(void)
|
||||
{
|
||||
u_int divisor;
|
||||
u_char dlbh;
|
||||
u_char dlbl;
|
||||
u_char cfcr;
|
||||
|
||||
cfcr = inb(comc_port + com_cfcr);
|
||||
outb(comc_port + com_cfcr, CFCR_DLAB | cfcr);
|
||||
|
||||
dlbl = inb(comc_port + com_dlbl);
|
||||
dlbh = inb(comc_port + com_dlbh);
|
||||
|
||||
outb(comc_port + com_cfcr, cfcr);
|
||||
|
||||
divisor = dlbh << 8 | dlbl;
|
||||
|
||||
/* XXX there should be more sanity checking. */
|
||||
if (divisor == 0)
|
||||
return (COMSPEED);
|
||||
return (COMC_DIV2BPS(divisor));
|
||||
}
|
29
sys/boot/pc98/libpc98/libpc98.h
Normal file
29
sys/boot/pc98/libpc98/libpc98.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 TAKAHASHI Yoshihiro <nyan@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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
void set_machine_type(void);
|
78
sys/boot/pc98/libpc98/pc98_sys.c
Normal file
78
sys/boot/pc98/libpc98/pc98_sys.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 TAKAHASHI Yoshihiro <nyan@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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <btxv86.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#define _KERNEL
|
||||
#include <pc98/pc98/pc98_machdep.h>
|
||||
|
||||
/*
|
||||
* Set machine type to PC98_SYSTEM_PARAMETER.
|
||||
*/
|
||||
void
|
||||
set_machine_type(void)
|
||||
{
|
||||
int i;
|
||||
u_long ret, data;
|
||||
|
||||
/* PC98_SYSTEM_PARAMETER (0x501) */
|
||||
ret = ((*(u_char *)PTOV(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) */
|
||||
for (i = data = 0; i < 4; i++)
|
||||
data += *((u_long *)PTOV(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 ((*(u_char *)PTOV(0xA1400)) & 0x80)
|
||||
ret |= M_NOTE;
|
||||
if (ret & M_NEC_PC98) {
|
||||
/* PC98_SYSTEM_PARAMETER(0x458) */
|
||||
if ((*(u_char *)PTOV(0xA1458)) & 0x80)
|
||||
ret |= M_H98;
|
||||
else
|
||||
ret |= M_NOT_H98;
|
||||
} else
|
||||
ret |= M_NOT_H98;
|
||||
|
||||
(*(u_long *)PTOV(0xA1620)) = ret;
|
||||
}
|
98
sys/boot/pc98/libpc98/time.c
Normal file
98
sys/boot/pc98/libpc98/time.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <btxv86.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include "bootstrap.h"
|
||||
#include "libi386.h"
|
||||
|
||||
static int bios_seconds(void);
|
||||
|
||||
/*
|
||||
* Return the BIOS time-of-day value.
|
||||
*
|
||||
* XXX uses undocumented BCD support from libstand.
|
||||
*/
|
||||
static int
|
||||
bios_seconds(void)
|
||||
{
|
||||
int hr, minute, sec;
|
||||
unsigned char bios_time[6];
|
||||
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x1c; /* int 0x1c, function 0 */
|
||||
v86.eax = 0x0000;
|
||||
v86.es = VTOPSEG(bios_time);
|
||||
v86.ebx = VTOPOFF(bios_time);
|
||||
v86int();
|
||||
|
||||
hr = bcd2bin(bios_time[3]);
|
||||
minute = bcd2bin(bios_time[4]);
|
||||
sec = bcd2bin(bios_time[5]);
|
||||
|
||||
return (hr * 3600 + minute * 60 + sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the time in seconds since the beginning of the day.
|
||||
*/
|
||||
time_t
|
||||
time(time_t *t)
|
||||
{
|
||||
static time_t lasttime;
|
||||
time_t now;
|
||||
|
||||
now = bios_seconds();
|
||||
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
period = (period + 500) / 1000;
|
||||
for( ; period != 0 ; period--)
|
||||
for(i=800;i != 0; i--)
|
||||
outb(0x5f,0); /* wait 600ns */
|
||||
}
|
596
sys/boot/pc98/libpc98/vidconsole.c
Normal file
596
sys/boot/pc98/libpc98/vidconsole.c
Normal file
@ -0,0 +1,596 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <bootstrap.h>
|
||||
#include <btxv86.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include "libi386.h"
|
||||
|
||||
#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
|
||||
#define MAXARGS 8
|
||||
#define DEFAULT_FGCOLOR 7
|
||||
#define DEFAULT_BGCOLOR 0
|
||||
|
||||
void end_term(void);
|
||||
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 CD(void);
|
||||
void CM(void);
|
||||
void HO(void);
|
||||
|
||||
static int args[MAXARGS], argc;
|
||||
static int fg_c, bg_c, curx, cury;
|
||||
static int esc;
|
||||
#endif
|
||||
|
||||
static unsigned short *crtat, *Crtat;
|
||||
static int row = 25, col = 80;
|
||||
#ifdef TERM_EMU
|
||||
static u_int8_t ibmpc_to_pc98[256] = {
|
||||
0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
|
||||
0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
|
||||
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
|
||||
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
|
||||
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
|
||||
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
|
||||
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
|
||||
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
|
||||
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
|
||||
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
|
||||
0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
|
||||
0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
|
||||
0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
|
||||
0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
|
||||
0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
|
||||
0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
|
||||
|
||||
0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
|
||||
0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
|
||||
0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
|
||||
0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
|
||||
0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
|
||||
0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
|
||||
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
|
||||
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
|
||||
0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
|
||||
0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
|
||||
0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
|
||||
0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
|
||||
0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
|
||||
0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
|
||||
0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
|
||||
0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
|
||||
};
|
||||
#define at2pc98(fg_at, bg_at) ibmpc_to_pc98[((bg_at) << 4) | (fg_at)]
|
||||
#endif /* TERM_EMU */
|
||||
|
||||
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, hw_cursor;
|
||||
|
||||
if (vidc_started && arg == 0)
|
||||
return (0);
|
||||
vidc_started = 1;
|
||||
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;
|
||||
#ifdef TERM_EMU
|
||||
/* Init terminal emulator */
|
||||
end_term();
|
||||
get_pos();
|
||||
curs_move(curx, cury);
|
||||
fg_c = DEFAULT_FGCOLOR;
|
||||
bg_c = DEFAULT_BGCOLOR;
|
||||
#endif
|
||||
for (i = 0; i < 10 && vidc_ischar(); i++)
|
||||
(void)vidc_getchar();
|
||||
return (0); /* XXX reinit? */
|
||||
}
|
||||
|
||||
static void
|
||||
beep(void)
|
||||
{
|
||||
|
||||
outb(0x37, 6);
|
||||
delay(40000);
|
||||
outb(0x37, 7);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
vidc_biosputchar(int c)
|
||||
{
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
vidc_rawputchar(int c)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (c == '\t')
|
||||
/* lame tab expansion */
|
||||
for (i = 0; i < 8; i++)
|
||||
vidc_rawputchar(' ');
|
||||
else {
|
||||
/* Emulate AH=0eh (teletype output) */
|
||||
switch(c) {
|
||||
case '\a':
|
||||
beep();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TERM_EMU
|
||||
|
||||
/* Get cursor position on the screen. Result is in edx. Sets
|
||||
* curx and cury appropriately.
|
||||
*/
|
||||
void
|
||||
get_pos(void)
|
||||
{
|
||||
int pos = crtat - Crtat;
|
||||
|
||||
curx = pos % col;
|
||||
cury = pos / col;
|
||||
}
|
||||
|
||||
/* Move cursor to x rows and y cols (0-based). */
|
||||
void
|
||||
curs_move(int x, int y)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 fgcol, int bgcol)
|
||||
{
|
||||
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(fgcol, bgcol);
|
||||
*cp++ = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
/* Write character and attribute at cursor position. */
|
||||
void
|
||||
write_char(int c, int fgcol, int bgcol)
|
||||
{
|
||||
|
||||
*crtat = (c == 0x5c ? 0xfc : (c & 0xff));
|
||||
*(crtat + 0x1000) = at2pc98(fgcol, bgcol);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/*
|
||||
* Screen manipulation functions. They use accumulated data in
|
||||
* args[] and argc variables.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Clear display from current position to end of screen */
|
||||
void
|
||||
CD(void)
|
||||
{
|
||||
int pos;
|
||||
|
||||
get_pos();
|
||||
for (pos = 0; crtat + pos <= Crtat + col * row; pos++) {
|
||||
*(crtat + pos) = ' ';
|
||||
*(crtat + pos + 0x1000) = at2pc98(fg_c, bg_c);
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
/* Clear internal state of the terminal emulation code */
|
||||
void
|
||||
end_term(void)
|
||||
{
|
||||
|
||||
esc = 0;
|
||||
argc = -1;
|
||||
}
|
||||
|
||||
/* Gracefully exit ESC-sequence processing in case of misunderstanding */
|
||||
void
|
||||
bail_out(int c)
|
||||
{
|
||||
char buf[16], *ch;
|
||||
int i;
|
||||
|
||||
if (esc) {
|
||||
vidc_rawputchar('\033');
|
||||
if (esc != '\033')
|
||||
vidc_rawputchar(esc);
|
||||
for (i = 0; i <= argc; ++i) {
|
||||
sprintf(buf, "%d", args[i]);
|
||||
ch = buf;
|
||||
while (*ch)
|
||||
vidc_rawputchar(*ch++);
|
||||
}
|
||||
}
|
||||
vidc_rawputchar(c);
|
||||
end_term();
|
||||
}
|
||||
|
||||
static void
|
||||
get_arg(int c)
|
||||
{
|
||||
|
||||
if (argc < 0)
|
||||
argc = 0;
|
||||
args[argc] *= 10;
|
||||
args[argc] += c - '0';
|
||||
}
|
||||
|
||||
/* Emulate basic capabilities of cons25 terminal */
|
||||
void
|
||||
vidc_term_emu(int c)
|
||||
{
|
||||
static int ansi_col[] = {
|
||||
0, 4, 2, 6, 1, 5, 3, 7,
|
||||
};
|
||||
int t;
|
||||
int i;
|
||||
|
||||
switch (esc) {
|
||||
case 0:
|
||||
switch (c) {
|
||||
case '\033':
|
||||
esc = c;
|
||||
break;
|
||||
default:
|
||||
vidc_rawputchar(c);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\033':
|
||||
switch (c) {
|
||||
case '[':
|
||||
esc = c;
|
||||
args[0] = 0;
|
||||
argc = -1;
|
||||
break;
|
||||
default:
|
||||
bail_out(c);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case '[':
|
||||
switch (c) {
|
||||
case ';':
|
||||
if (argc < 0) /* XXX */
|
||||
argc = 0;
|
||||
else if (argc + 1 >= MAXARGS)
|
||||
bail_out(c);
|
||||
else
|
||||
args[++argc] = 0;
|
||||
break;
|
||||
case 'H':
|
||||
if (argc < 0)
|
||||
HO();
|
||||
else if (argc == 1)
|
||||
CM();
|
||||
else
|
||||
bail_out(c);
|
||||
break;
|
||||
case 'J':
|
||||
if (argc < 0)
|
||||
CD();
|
||||
else
|
||||
bail_out(c);
|
||||
break;
|
||||
case 'm':
|
||||
if (argc < 0) {
|
||||
fg_c = DEFAULT_FGCOLOR;
|
||||
bg_c = DEFAULT_BGCOLOR;
|
||||
}
|
||||
for (i = 0; i <= argc; ++i) {
|
||||
switch (args[i]) {
|
||||
case 0: /* back to normal */
|
||||
fg_c = DEFAULT_FGCOLOR;
|
||||
bg_c = DEFAULT_BGCOLOR;
|
||||
break;
|
||||
case 1: /* bold */
|
||||
fg_c |= 0x8;
|
||||
break;
|
||||
case 4: /* underline */
|
||||
case 5: /* blink */
|
||||
bg_c |= 0x8;
|
||||
break;
|
||||
case 7: /* reverse */
|
||||
t = fg_c;
|
||||
fg_c = bg_c;
|
||||
bg_c = t;
|
||||
break;
|
||||
case 30: case 31: case 32: case 33:
|
||||
case 34: case 35: case 36: case 37:
|
||||
fg_c = ansi_col[args[i] - 30];
|
||||
break;
|
||||
case 39: /* normal */
|
||||
fg_c = DEFAULT_FGCOLOR;
|
||||
break;
|
||||
case 40: case 41: case 42: case 43:
|
||||
case 44: case 45: case 46: case 47:
|
||||
bg_c = ansi_col[args[i] - 40];
|
||||
break;
|
||||
case 49: /* normal */
|
||||
bg_c = DEFAULT_BGCOLOR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
end_term();
|
||||
break;
|
||||
default:
|
||||
if (isdigit(c))
|
||||
get_arg(c);
|
||||
else
|
||||
bail_out(c);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
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;
|
||||
v86.addr = 0x18;
|
||||
v86.eax = 0x0;
|
||||
v86int();
|
||||
return (v86.eax & 0xff);
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vidc_ischar(void)
|
||||
{
|
||||
|
||||
v86.ctl = 0;
|
||||
v86.addr = 0x18;
|
||||
v86.eax = 0x100;
|
||||
v86int();
|
||||
return ((v86.ebx >> 8) & 0x1);
|
||||
}
|
||||
|
||||
#if KEYBOARD_PROBE
|
||||
static int
|
||||
probe_keyboard(void)
|
||||
{
|
||||
return (*(u_char *)PTOV(0xA1481) & 0x48);
|
||||
}
|
||||
#endif /* KEYBOARD_PROBE */
|
99
sys/boot/pc98/loader/Makefile
Normal file
99
sys/boot/pc98/loader/Makefile
Normal file
@ -0,0 +1,99 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
MK_SSP= no
|
||||
MAN=
|
||||
|
||||
LOADER?= loader
|
||||
PROG= ${LOADER}.sym
|
||||
INTERNALPROG=
|
||||
NEWVERSWHAT= "bootstrap loader" pc98
|
||||
VERSION_FILE= ${.CURDIR}/../../i386/loader/version
|
||||
|
||||
# architecture-specific loader code
|
||||
SRCS= main.c conf.c vers.c
|
||||
.PATH: ${.CURDIR}/../../i386/loader
|
||||
|
||||
# Enable PXE TFTP or NFS support, not both.
|
||||
.if defined(LOADER_TFTP_SUPPORT)
|
||||
CFLAGS+= -DLOADER_TFTP_SUPPORT
|
||||
.else
|
||||
CFLAGS+= -DLOADER_NFS_SUPPORT
|
||||
.endif
|
||||
|
||||
# Include bcache code.
|
||||
HAVE_BCACHE= yes
|
||||
|
||||
# Enable PnP and ISA-PnP code.
|
||||
HAVE_PNP= yes
|
||||
HAVE_ISABUS= yes
|
||||
|
||||
.if ${MK_FORTH} != "no"
|
||||
# Enable BootForth
|
||||
BOOT_FORTH= yes
|
||||
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386
|
||||
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
|
||||
.endif
|
||||
|
||||
.if defined(LOADER_BZIP2_SUPPORT)
|
||||
CFLAGS+= -DLOADER_BZIP2_SUPPORT
|
||||
.endif
|
||||
.if !defined(LOADER_NO_GZIP_SUPPORT)
|
||||
CFLAGS+= -DLOADER_GZIP_SUPPORT
|
||||
.endif
|
||||
|
||||
# Always add MI sources
|
||||
.PATH: ${.CURDIR}/../../common
|
||||
.include "${.CURDIR}/../../common/Makefile.inc"
|
||||
CFLAGS+= -I${.CURDIR}/../../common
|
||||
CFLAGS+= -I${.CURDIR}/../../i386
|
||||
CFLAGS+= -I.
|
||||
|
||||
CLEANFILES= ${LOADER} ${LOADER}.bin loader.help
|
||||
|
||||
CFLAGS+= -Wall
|
||||
LDFLAGS= -static -Ttext 0x0
|
||||
|
||||
# pc98 standalone support library
|
||||
LIBPC98= ${.OBJDIR}/../libpc98/libpc98.a
|
||||
CFLAGS+= -I${.CURDIR}/..
|
||||
|
||||
LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a
|
||||
|
||||
# BTX components
|
||||
CFLAGS+= -I${.CURDIR}/../btx/lib
|
||||
|
||||
# Debug me!
|
||||
#CFLAGS+= -g
|
||||
#LDFLAGS+= -g
|
||||
|
||||
# Pick up ../Makefile.inc early.
|
||||
.include <bsd.init.mk>
|
||||
|
||||
${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN}
|
||||
btxld -v -f aout -e ${LOADER_ADDRESS} -o ${.TARGET} -l ${BTXLDR} \
|
||||
-b ${BTXKERN} ${LOADER}.bin
|
||||
|
||||
${LOADER}.bin: ${LOADER}.sym
|
||||
cp ${.ALLSRC} ${.TARGET}
|
||||
strip -R .comment -R .note ${.TARGET}
|
||||
|
||||
loader.help: help.common help.pc98
|
||||
cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
|
||||
|
||||
FILES= ${LOADER}
|
||||
# XXX INSTALLFLAGS_loader= -b
|
||||
FILESMODE_${LOADER}= ${BINMODE} -b
|
||||
|
||||
.PATH: ${.CURDIR}/../../forth
|
||||
.include "${.CURDIR}/../../forth/Makefile.inc"
|
||||
|
||||
FILES+= ${.CURDIR}/../../i386/loader/loader.rc menu.rc
|
||||
|
||||
# XXX crt0.o needs to be first for pxeboot(8) to work
|
||||
OBJS= ${BTXCRT}
|
||||
|
||||
DPADD= ${LIBFICL} ${LIBPC98} ${LIBSTAND}
|
||||
LDADD= ${LIBFICL} ${LIBPC98} ${LIBSTAND}
|
||||
|
||||
.include <bsd.prog.mk>
|
116
sys/boot/pc98/loader/conf.c
Normal file
116
sys/boot/pc98/loader/conf.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <bootstrap.h>
|
||||
#include "libi386/libi386.h"
|
||||
|
||||
/*
|
||||
* We could use linker sets for some or all of these, but
|
||||
* then we would have to control what ended up linked into
|
||||
* the bootstrap. So it's easier to conditionalise things
|
||||
* here.
|
||||
*
|
||||
* XXX rename these arrays to be consistent and less namespace-hostile
|
||||
*
|
||||
* XXX as libi386 and biosboot merge, some of these can become linker sets.
|
||||
*/
|
||||
|
||||
/* Exported for libstand */
|
||||
struct devsw *devsw[] = {
|
||||
&bioscd,
|
||||
&biosdisk,
|
||||
#if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT)
|
||||
&pxedisk,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
struct fs_ops *file_system[] = {
|
||||
&ufs_fsops,
|
||||
&ext2fs_fsops,
|
||||
&dosfs_fsops,
|
||||
&cd9660_fsops,
|
||||
#ifdef LOADER_NFS_SUPPORT
|
||||
&nfs_fsops,
|
||||
#endif
|
||||
#ifdef LOADER_TFTP_SUPPORT
|
||||
&tftp_fsops,
|
||||
#endif
|
||||
#ifdef LOADER_GZIP_SUPPORT
|
||||
&gzipfs_fsops,
|
||||
#endif
|
||||
#ifdef LOADER_BZIP2_SUPPORT
|
||||
&bzipfs_fsops,
|
||||
#endif
|
||||
&splitfs_fsops,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Exported for i386 only */
|
||||
/*
|
||||
* Sort formats so that those that can detect based on arguments
|
||||
* rather than reading the file go first.
|
||||
*/
|
||||
extern struct file_format i386_elf;
|
||||
extern struct file_format i386_elf_obj;
|
||||
|
||||
struct file_format *file_formats[] = {
|
||||
&i386_elf,
|
||||
&i386_elf_obj,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Consoles
|
||||
*
|
||||
* We don't prototype these in libi386.h because they require
|
||||
* data structures from bootstrap.h as well.
|
||||
*/
|
||||
extern struct console vidconsole;
|
||||
extern struct console comconsole;
|
||||
extern struct console nullconsole;
|
||||
|
||||
struct console *consoles[] = {
|
||||
&vidconsole,
|
||||
&comconsole,
|
||||
&nullconsole,
|
||||
NULL
|
||||
};
|
||||
|
||||
extern struct pnphandler isapnphandler;
|
||||
extern struct pnphandler biospnphandler;
|
||||
extern struct pnphandler biospcihandler;
|
||||
|
||||
struct pnphandler *pnphandlers[] = {
|
||||
&biospnphandler, /* should go first, as it may set isapnp_readport */
|
||||
&isapnphandler,
|
||||
&biospcihandler,
|
||||
NULL
|
||||
};
|
38
sys/boot/pc98/loader/help.pc98
Normal file
38
sys/boot/pc98/loader/help.pc98
Normal file
@ -0,0 +1,38 @@
|
||||
################################################################################
|
||||
# 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 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.
|
||||
|
||||
################################################################################
|
322
sys/boot/pc98/loader/main.c
Normal file
322
sys/boot/pc98/loader/main.c
Normal file
@ -0,0 +1,322 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* MD bootstrap main() and assorted miscellaneous
|
||||
* commands.
|
||||
*/
|
||||
|
||||
#include <stand.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "common/bootargs.h"
|
||||
#include "libi386/libi386.h"
|
||||
#include "libpc98/libpc98.h"
|
||||
#include "btxv86.h"
|
||||
|
||||
CTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE);
|
||||
CTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO);
|
||||
CTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS);
|
||||
CTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE);
|
||||
|
||||
/* Arguments passed in from the boot1/boot2 loader */
|
||||
static struct bootargs *kargs;
|
||||
|
||||
static u_int32_t initial_howto;
|
||||
static u_int32_t initial_bootdev;
|
||||
static struct bootinfo *initial_bootinfo;
|
||||
|
||||
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);
|
||||
void exit(int code);
|
||||
|
||||
/* from vers.c */
|
||||
extern char bootprog_info[];
|
||||
|
||||
/* XXX debugging */
|
||||
extern char end[];
|
||||
|
||||
static void *heap_top;
|
||||
static void *heap_bottom;
|
||||
|
||||
static uint64_t
|
||||
pc98_loadaddr(u_int type, void *data, uint64_t addr)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (type == LOAD_ELF)
|
||||
return (roundup(addr, PAGE_SIZE));
|
||||
|
||||
/* We cannot use 15M-16M area on pc98. */
|
||||
if (type == LOAD_RAW && addr < 0x1000000 && stat(data, &st) == 0 &&
|
||||
(st.st_size == -1 || addr + st.st_size > 0xf00000))
|
||||
addr = 0x1000000;
|
||||
return (addr);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Set machine type to PC98_SYSTEM_PARAMETER. */
|
||||
set_machine_type();
|
||||
|
||||
/* Pick up arguments */
|
||||
kargs = (void *)__args;
|
||||
initial_howto = kargs->howto;
|
||||
initial_bootdev = kargs->bootdev;
|
||||
initial_bootinfo = kargs->bootinfo ? (struct bootinfo *)PTOV(kargs->bootinfo) : NULL;
|
||||
|
||||
/* Initialize the v86 register set to a known-good state. */
|
||||
bzero(&v86, sizeof(v86));
|
||||
v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
|
||||
|
||||
/*
|
||||
* Initialise the heap as early as possible. Once this is done, malloc() is usable.
|
||||
*/
|
||||
bios_getmem();
|
||||
|
||||
#if defined(LOADER_BZIP2_SUPPORT)
|
||||
if (high_heap_size > 0) {
|
||||
heap_top = PTOV(high_heap_base + high_heap_size);
|
||||
heap_bottom = PTOV(high_heap_base);
|
||||
if (high_heap_base < memtop_copyin)
|
||||
memtop_copyin = high_heap_base;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
heap_top = (void *)PTOV(bios_basemem);
|
||||
heap_bottom = (void *)end;
|
||||
}
|
||||
setheap(heap_bottom, heap_top);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
bi_setboothowto(initial_howto);
|
||||
if (initial_howto & RB_MULTIPLE) {
|
||||
if (initial_howto & RB_SERIAL)
|
||||
setenv("console", "comconsole vidconsole", 1);
|
||||
else
|
||||
setenv("console", "vidconsole comconsole", 1);
|
||||
} else if (initial_howto & RB_SERIAL)
|
||||
setenv("console", "comconsole", 1);
|
||||
else if (initial_howto & RB_MUTE)
|
||||
setenv("console", "nullconsole", 1);
|
||||
cons_probe();
|
||||
|
||||
/*
|
||||
* Initialise the block cache. Set the upper limit.
|
||||
*/
|
||||
bcache_init(32768, 512);
|
||||
|
||||
/*
|
||||
* Special handling for PXE and CD booting.
|
||||
*/
|
||||
if (kargs->bootinfo == 0) {
|
||||
/*
|
||||
* We only want the PXE disk to try to init itself in the below
|
||||
* walk through devsw if we actually booted off of PXE.
|
||||
*/
|
||||
if (kargs->bootflags & KARGS_FLAGS_PXE)
|
||||
pxe_enable(kargs->pxeinfo ? PTOV(kargs->pxeinfo) : NULL);
|
||||
else if (kargs->bootflags & KARGS_FLAGS_CD)
|
||||
bc_add(initial_bootdev);
|
||||
}
|
||||
|
||||
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;
|
||||
archsw.arch_loadaddr = pc98_loadaddr;
|
||||
|
||||
/*
|
||||
* 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("BIOS %dkB/%dkB available memory\n", bios_basemem / 1024, bios_extmem / 1024);
|
||||
if (initial_bootinfo != NULL) {
|
||||
initial_bootinfo->bi_basemem = bios_basemem / 1024;
|
||||
initial_bootinfo->bi_extmem = bios_extmem / 1024;
|
||||
}
|
||||
|
||||
printf("\n%s", bootprog_info);
|
||||
|
||||
extract_currdev(); /* set $currdev and $loaddev */
|
||||
setenv("LINES", "24", 1); /* optional */
|
||||
|
||||
interact(NULL); /* doesn't return */
|
||||
|
||||
/* if we ever get here, it is an error */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 new_currdev;
|
||||
int major;
|
||||
int biosdev = -1;
|
||||
|
||||
/* Assume we are booting from a BIOS disk by default */
|
||||
new_currdev.d_dev = &biosdisk;
|
||||
|
||||
/* new-style boot loaders such as pxeldr and cdldr */
|
||||
if (kargs->bootinfo == 0) {
|
||||
if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) {
|
||||
/* we are booting from a CD with cdboot */
|
||||
new_currdev.d_dev = &bioscd;
|
||||
new_currdev.d_unit = bc_bios2unit(initial_bootdev);
|
||||
} else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) {
|
||||
/* we are booting from pxeldr */
|
||||
new_currdev.d_dev = &pxedisk;
|
||||
new_currdev.d_unit = 0;
|
||||
} else {
|
||||
/* we don't know what our boot device is */
|
||||
new_currdev.d_kind.biosdisk.slice = -1;
|
||||
new_currdev.d_kind.biosdisk.partition = 0;
|
||||
biosdev = -1;
|
||||
}
|
||||
} else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
|
||||
/* The passed-in boot device is bad */
|
||||
new_currdev.d_kind.biosdisk.slice = -1;
|
||||
new_currdev.d_kind.biosdisk.partition = 0;
|
||||
biosdev = -1;
|
||||
} else {
|
||||
new_currdev.d_kind.biosdisk.slice = B_SLICE(initial_bootdev) - 1;
|
||||
new_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 lose 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).
|
||||
*/
|
||||
if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2)) { /* biosdev doesn't match major */
|
||||
if (B_TYPE(initial_bootdev) == 6)
|
||||
biosdev = 0x30 + B_UNIT(initial_bootdev);
|
||||
else
|
||||
biosdev = (major << 3) + 0x80 + B_UNIT(initial_bootdev);
|
||||
}
|
||||
}
|
||||
new_currdev.d_type = new_currdev.d_dev->dv_type;
|
||||
|
||||
/*
|
||||
* If we are booting off of a BIOS disk and we didn't succeed in determining
|
||||
* which one we booted off of, just use disk0: as a reasonable default.
|
||||
*/
|
||||
if ((new_currdev.d_type == biosdisk.dv_type) &&
|
||||
((new_currdev.d_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);
|
||||
new_currdev.d_unit = 0;
|
||||
}
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
|
||||
i386_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
|
||||
env_nounset);
|
||||
}
|
||||
|
||||
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
|
||||
|
||||
static int
|
||||
command_reboot(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; devsw[i] != NULL; ++i)
|
||||
if (devsw[i]->dv_cleanup != NULL)
|
||||
(devsw[i]->dv_cleanup)();
|
||||
|
||||
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, upper limit at %p\n", heap_bottom,
|
||||
sbrk(0), heap_top);
|
||||
return(CMD_OK);
|
||||
}
|
||||
|
||||
/* ISA bus access functions for PnP. */
|
||||
static int
|
||||
isa_inb(int port)
|
||||
{
|
||||
|
||||
return (inb(port));
|
||||
}
|
||||
|
||||
static void
|
||||
isa_outb(int port, int value)
|
||||
{
|
||||
|
||||
outb(port, value);
|
||||
}
|
25
sys/boot/pc98/pc98boot/Makefile
Normal file
25
sys/boot/pc98/pc98boot/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# $FreeBSD$
|
||||
|
||||
FILES= ${BOOT}
|
||||
CLEANFILES= ${BOOT} ${BOOT}.part
|
||||
|
||||
BOOT= pc98boot
|
||||
|
||||
.if exists(${.OBJDIR}/../boot0)
|
||||
BOOT0= ${.OBJDIR}/../boot0/boot0
|
||||
.else
|
||||
BOOT0= ${.CURDIR}/../boot0/boot0
|
||||
.endif
|
||||
.if exists(${.OBJDIR}/../boot0.5)
|
||||
BOOT05= ${.OBJDIR}/../boot0.5/boot0.5
|
||||
.else
|
||||
BOOT05= ${.CURDIR}/../boot0.5/boot0.5
|
||||
.endif
|
||||
|
||||
${BOOT}: ${BOOT0} ${BOOT05} ${BOOT}.part
|
||||
cat ${BOOT0} ${BOOT}.part ${BOOT05} > ${.TARGET}
|
||||
|
||||
${BOOT}.part:
|
||||
${DD} if=/dev/zero of=${.TARGET} bs=512 count=1
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -973,7 +973,7 @@ ffs_write_file(union dinode *din, uint32_t ino, void *buf, fsinfo_t *fsopts)
|
||||
errno = bwrite(bp);
|
||||
if (errno != 0)
|
||||
goto bad_ffs_write_file;
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
if (!isfile)
|
||||
p += chunk;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buf.c,v 1.12 2004/06/20 22:20:18 jmc Exp $ */
|
||||
/* $NetBSD: buf.c,v 1.13 2004/06/20 22:20:18 jmc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wasabi Systems, Inc.
|
||||
@ -60,10 +60,12 @@ extern int sectorsize; /* XXX: from ffs.c & mkfs.c */
|
||||
TAILQ_HEAD(buftailhead,buf) buftail;
|
||||
|
||||
int
|
||||
bread(int fd, struct fs *fs, daddr_t blkno, int size, struct buf **bpp)
|
||||
bread(struct vnode *vp, daddr_t blkno, int size, struct ucred *u1 __unused,
|
||||
struct buf **bpp)
|
||||
{
|
||||
off_t offset;
|
||||
ssize_t rv;
|
||||
struct fs *fs = vp->fs;
|
||||
|
||||
assert (fs != NULL);
|
||||
assert (bpp != NULL);
|
||||
@ -71,7 +73,7 @@ bread(int fd, struct fs *fs, daddr_t blkno, int size, struct buf **bpp)
|
||||
if (debug & DEBUG_BUF_BREAD)
|
||||
printf("bread: fs %p blkno %lld size %d\n",
|
||||
fs, (long long)blkno, size);
|
||||
*bpp = getblk(fd, fs, blkno, size);
|
||||
*bpp = getblk(vp, blkno, size, 0, 0, 0);
|
||||
offset = (*bpp)->b_blkno * sectorsize; /* XXX */
|
||||
if (debug & DEBUG_BUF_BREAD)
|
||||
printf("bread: bp %p blkno %lld offset %lld bcount %ld\n",
|
||||
@ -95,7 +97,7 @@ bread(int fd, struct fs *fs, daddr_t blkno, int size, struct buf **bpp)
|
||||
}
|
||||
|
||||
void
|
||||
brelse(struct buf *bp)
|
||||
brelse(struct buf *bp, int u1 __unused)
|
||||
{
|
||||
|
||||
assert (bp != NULL);
|
||||
@ -174,12 +176,16 @@ bcleanup(void)
|
||||
}
|
||||
|
||||
struct buf *
|
||||
getblk(int fd, struct fs *fs, daddr_t blkno, int size)
|
||||
getblk(struct vnode *vp, daddr_t blkno, int size, int u1 __unused,
|
||||
int u2 __unused, int u3 __unused)
|
||||
{
|
||||
static int buftailinitted;
|
||||
struct buf *bp;
|
||||
void *n;
|
||||
int fd = vp->fd;
|
||||
struct fs *fs = vp->fs;
|
||||
|
||||
blkno += vp->offset;
|
||||
assert (fs != NULL);
|
||||
if (debug & DEBUG_BUF_GETBLK)
|
||||
printf("getblk: fs %p blkno %lld size %d\n", fs,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buf.h,v 1.2 2001/11/02 03:12:49 lukem Exp $ */
|
||||
/* $NetBSD: buf.h,v 1.3 2001/11/02 03:12:49 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wasabi Systems, Inc.
|
||||
@ -43,6 +43,15 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
struct ucred;
|
||||
|
||||
struct vnode {
|
||||
int fd;
|
||||
void *fs;
|
||||
void *v_data;
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct buf {
|
||||
void * b_data;
|
||||
long b_bufsize;
|
||||
@ -56,10 +65,11 @@ struct buf {
|
||||
};
|
||||
|
||||
void bcleanup(void);
|
||||
int bread(int, struct fs *, daddr_t, int, struct buf **);
|
||||
void brelse(struct buf *);
|
||||
int bread(struct vnode *, daddr_t, int, struct ucred *,
|
||||
struct buf **);
|
||||
void brelse(struct buf *, int);
|
||||
int bwrite(struct buf *);
|
||||
struct buf * getblk(int, struct fs *, daddr_t, int);
|
||||
struct buf * getblk(struct vnode *, daddr_t, int, int, int, int);
|
||||
|
||||
#define bdwrite(bp) bwrite(bp)
|
||||
#define clrbuf(bp) memset((bp)->b_data, 0, (u_int)(bp)->b_bcount)
|
||||
|
@ -297,19 +297,20 @@ ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, int size)
|
||||
int error, frags, allocsiz, i;
|
||||
struct fs *fs = ip->i_fs;
|
||||
const int needswap = UFS_FSNEEDSWAP(fs);
|
||||
struct vnode vp = { ip->i_fd, ip->i_fs, NULL, 0 };
|
||||
|
||||
if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
|
||||
return (0);
|
||||
error = bread(ip->i_fd, ip->i_fs, fsbtodb(fs, cgtod(fs, cg)),
|
||||
(int)fs->fs_cgsize, &bp);
|
||||
error = bread(&vp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
|
||||
NULL, &bp);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return (0);
|
||||
}
|
||||
cgp = (struct cg *)bp->b_data;
|
||||
if (!cg_chkmagic_swap(cgp, needswap) ||
|
||||
(cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return (0);
|
||||
}
|
||||
if (size == fs->fs_bsize) {
|
||||
@ -332,7 +333,7 @@ ffs_alloccg(struct inode *ip, int cg, daddr_t bpref, int size)
|
||||
* allocated, and hacked up
|
||||
*/
|
||||
if (cgp->cg_cs.cs_nbfree == 0) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return (0);
|
||||
}
|
||||
bno = ffs_alloccgblk(ip, bp, bpref);
|
||||
@ -432,6 +433,7 @@ ffs_blkfree(struct inode *ip, daddr_t bno, long size)
|
||||
int i, error, cg, blk, frags, bbase;
|
||||
struct fs *fs = ip->i_fs;
|
||||
const int needswap = UFS_FSNEEDSWAP(fs);
|
||||
struct vnode vp = { ip->i_fd, ip->i_fs, NULL, 0 };
|
||||
|
||||
if (size > fs->fs_bsize || fragoff(fs, size) != 0 ||
|
||||
fragnum(fs, bno) + numfrags(fs, size) > fs->fs_frag) {
|
||||
@ -444,15 +446,15 @@ ffs_blkfree(struct inode *ip, daddr_t bno, long size)
|
||||
(uintmax_t)ip->i_number);
|
||||
return;
|
||||
}
|
||||
error = bread(ip->i_fd, ip->i_fs, fsbtodb(fs, cgtod(fs, cg)),
|
||||
(int)fs->fs_cgsize, &bp);
|
||||
error = bread(&vp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
|
||||
NULL, &bp);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return;
|
||||
}
|
||||
cgp = (struct cg *)bp->b_data;
|
||||
if (!cg_chkmagic_swap(cgp, needswap)) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return;
|
||||
}
|
||||
cgbno = dtogd(fs, bno);
|
||||
|
@ -89,6 +89,7 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
int32_t *allocblk, allociblk[NIADDR + 1];
|
||||
int32_t *allocib;
|
||||
const int needswap = UFS_FSNEEDSWAP(fs);
|
||||
struct vnode vp = { ip->i_fd, ip->i_fs, NULL, 0 };
|
||||
|
||||
lbn = lblkno(fs, offset);
|
||||
size = blkoff(fs, offset) + bufsize;
|
||||
@ -132,10 +133,10 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
if (bpp != NULL) {
|
||||
error = bread(ip->i_fd, ip->i_fs, lbn,
|
||||
fs->fs_bsize, bpp);
|
||||
error = bread(&vp, lbn, fs->fs_bsize, NULL,
|
||||
bpp);
|
||||
if (error) {
|
||||
brelse(*bpp);
|
||||
brelse(*bpp, 0);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
@ -158,10 +159,10 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
if (bpp != NULL) {
|
||||
error = bread(ip->i_fd, ip->i_fs, lbn,
|
||||
osize, bpp);
|
||||
error = bread(&vp, lbn, osize, NULL,
|
||||
bpp);
|
||||
if (error) {
|
||||
brelse(*bpp);
|
||||
brelse(*bpp, 0);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
@ -188,7 +189,7 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
if (error)
|
||||
return (error);
|
||||
if (bpp != NULL) {
|
||||
bp = getblk(ip->i_fd, ip->i_fs, lbn, nsize);
|
||||
bp = getblk(&vp, lbn, nsize, 0, 0, 0);
|
||||
bp->b_blkno = fsbtodb(fs, newb);
|
||||
clrbuf(bp);
|
||||
*bpp = bp;
|
||||
@ -226,7 +227,7 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
return error;
|
||||
nb = newb;
|
||||
*allocblk++ = nb;
|
||||
bp = getblk(ip->i_fd, ip->i_fs, indirs[1].in_lbn, fs->fs_bsize);
|
||||
bp = getblk(&vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, 0);
|
||||
bp->b_blkno = fsbtodb(fs, nb);
|
||||
clrbuf(bp);
|
||||
/*
|
||||
@ -244,10 +245,9 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
for (i = 1;;) {
|
||||
error = bread(ip->i_fd, ip->i_fs, indirs[i].in_lbn,
|
||||
fs->fs_bsize, &bp);
|
||||
error = bread(&vp, indirs[i].in_lbn, fs->fs_bsize, NULL, &bp);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
bap = (int32_t *)bp->b_data;
|
||||
@ -256,20 +256,19 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
break;
|
||||
i++;
|
||||
if (nb != 0) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
continue;
|
||||
}
|
||||
if (pref == 0)
|
||||
pref = ffs_blkpref_ufs1(ip, lbn, 0, (int32_t *)0);
|
||||
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, &newb);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
nb = newb;
|
||||
*allocblk++ = nb;
|
||||
nbp = getblk(ip->i_fd, ip->i_fs, indirs[i].in_lbn,
|
||||
fs->fs_bsize);
|
||||
nbp = getblk(&vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0, 0);
|
||||
nbp->b_blkno = fsbtodb(fs, nb);
|
||||
clrbuf(nbp);
|
||||
/*
|
||||
@ -278,7 +277,7 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
if ((error = bwrite(nbp)) != 0) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
bap[indirs[i - 1].in_off] = ufs_rw32(nb, needswap);
|
||||
@ -294,13 +293,13 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
pref = ffs_blkpref_ufs1(ip, lbn, indirs[num].in_off, &bap[0]);
|
||||
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, &newb);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
nb = newb;
|
||||
*allocblk++ = nb;
|
||||
if (bpp != NULL) {
|
||||
nbp = getblk(ip->i_fd, ip->i_fs, lbn, fs->fs_bsize);
|
||||
nbp = getblk(&vp, lbn, fs->fs_bsize, 0, 0, 0);
|
||||
nbp->b_blkno = fsbtodb(fs, nb);
|
||||
clrbuf(nbp);
|
||||
*bpp = nbp;
|
||||
@ -314,11 +313,11 @@ ffs_balloc_ufs1(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
bwrite(bp);
|
||||
return (0);
|
||||
}
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
if (bpp != NULL) {
|
||||
error = bread(ip->i_fd, ip->i_fs, lbn, (int)fs->fs_bsize, &nbp);
|
||||
error = bread(&vp, lbn, (int)fs->fs_bsize, NULL, &nbp);
|
||||
if (error) {
|
||||
brelse(nbp);
|
||||
brelse(nbp, 0);
|
||||
return error;
|
||||
}
|
||||
*bpp = nbp;
|
||||
@ -340,6 +339,7 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
int64_t *allocblk, allociblk[NIADDR + 1];
|
||||
int64_t *allocib;
|
||||
const int needswap = UFS_FSNEEDSWAP(fs);
|
||||
struct vnode vp = { ip->i_fd, ip->i_fs, NULL, 0 };
|
||||
|
||||
lbn = lblkno(fs, offset);
|
||||
size = blkoff(fs, offset) + bufsize;
|
||||
@ -383,10 +383,10 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
if (bpp != NULL) {
|
||||
error = bread(ip->i_fd, ip->i_fs, lbn,
|
||||
fs->fs_bsize, bpp);
|
||||
error = bread(&vp, lbn, fs->fs_bsize, NULL,
|
||||
bpp);
|
||||
if (error) {
|
||||
brelse(*bpp);
|
||||
brelse(*bpp, 0);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
@ -409,10 +409,10 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
if (bpp != NULL) {
|
||||
error = bread(ip->i_fd, ip->i_fs, lbn,
|
||||
osize, bpp);
|
||||
error = bread(&vp, lbn, osize, NULL,
|
||||
bpp);
|
||||
if (error) {
|
||||
brelse(*bpp);
|
||||
brelse(*bpp, 0);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
@ -439,7 +439,7 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
if (error)
|
||||
return (error);
|
||||
if (bpp != NULL) {
|
||||
bp = getblk(ip->i_fd, ip->i_fs, lbn, nsize);
|
||||
bp = getblk(&vp, lbn, nsize, 0, 0, 0);
|
||||
bp->b_blkno = fsbtodb(fs, newb);
|
||||
clrbuf(bp);
|
||||
*bpp = bp;
|
||||
@ -477,7 +477,7 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
return error;
|
||||
nb = newb;
|
||||
*allocblk++ = nb;
|
||||
bp = getblk(ip->i_fd, ip->i_fs, indirs[1].in_lbn, fs->fs_bsize);
|
||||
bp = getblk(&vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, 0);
|
||||
bp->b_blkno = fsbtodb(fs, nb);
|
||||
clrbuf(bp);
|
||||
/*
|
||||
@ -495,10 +495,9 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
for (i = 1;;) {
|
||||
error = bread(ip->i_fd, ip->i_fs, indirs[i].in_lbn,
|
||||
fs->fs_bsize, &bp);
|
||||
error = bread(&vp, indirs[i].in_lbn, fs->fs_bsize, NULL, &bp);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
bap = (int64_t *)bp->b_data;
|
||||
@ -507,20 +506,19 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
break;
|
||||
i++;
|
||||
if (nb != 0) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
continue;
|
||||
}
|
||||
if (pref == 0)
|
||||
pref = ffs_blkpref_ufs2(ip, lbn, 0, (int64_t *)0);
|
||||
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, &newb);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
nb = newb;
|
||||
*allocblk++ = nb;
|
||||
nbp = getblk(ip->i_fd, ip->i_fs, indirs[i].in_lbn,
|
||||
fs->fs_bsize);
|
||||
nbp = getblk(&vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0, 0);
|
||||
nbp->b_blkno = fsbtodb(fs, nb);
|
||||
clrbuf(nbp);
|
||||
/*
|
||||
@ -529,7 +527,7 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
*/
|
||||
|
||||
if ((error = bwrite(nbp)) != 0) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
bap[indirs[i - 1].in_off] = ufs_rw64(nb, needswap);
|
||||
@ -545,13 +543,13 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
pref = ffs_blkpref_ufs2(ip, lbn, indirs[num].in_off, &bap[0]);
|
||||
error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, &newb);
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
return error;
|
||||
}
|
||||
nb = newb;
|
||||
*allocblk++ = nb;
|
||||
if (bpp != NULL) {
|
||||
nbp = getblk(ip->i_fd, ip->i_fs, lbn, fs->fs_bsize);
|
||||
nbp = getblk(&vp, lbn, fs->fs_bsize, 0, 0, 0);
|
||||
nbp->b_blkno = fsbtodb(fs, nb);
|
||||
clrbuf(nbp);
|
||||
*bpp = nbp;
|
||||
@ -565,11 +563,11 @@ ffs_balloc_ufs2(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
|
||||
bwrite(bp);
|
||||
return (0);
|
||||
}
|
||||
brelse(bp);
|
||||
brelse(bp, 0);
|
||||
if (bpp != NULL) {
|
||||
error = bread(ip->i_fd, ip->i_fs, lbn, (int)fs->fs_bsize, &nbp);
|
||||
error = bread(&vp, lbn, (int)fs->fs_bsize, NULL, &nbp);
|
||||
if (error) {
|
||||
brelse(nbp);
|
||||
brelse(nbp, 0);
|
||||
return error;
|
||||
}
|
||||
*bpp = nbp;
|
||||
|
Loading…
Reference in New Issue
Block a user