svn commit: r202355 - stable/7/sys/boot/pc98/boot2

Takahashi Yoshihiro nyan at FreeBSD.org
Fri Jan 15 12:45:23 UTC 2010


Author: nyan
Date: Fri Jan 15 12:45:23 2010
New Revision: 202355
URL: http://svn.freebsd.org/changeset/base/202355

Log:
  MFC: revision 201342
  
    Reimplement the boot2 for pc98 completely.
    It's based on the newest i386's one and has the advantage of:
  
     - ELF binary support.
     - UFS2 filesystem support.
     - Many FreeBSD slices support on a disk.

Added:
  stable/7/sys/boot/pc98/boot2/boot1.S
     - copied unchanged from r201342, head/sys/boot/pc98/boot2/boot1.S
  stable/7/sys/boot/pc98/boot2/boot2.c
     - copied unchanged from r201342, head/sys/boot/pc98/boot2/boot2.c
Deleted:
  stable/7/sys/boot/pc98/boot2/asm.S
  stable/7/sys/boot/pc98/boot2/asm.h
  stable/7/sys/boot/pc98/boot2/bios.S
  stable/7/sys/boot/pc98/boot2/boot.c
  stable/7/sys/boot/pc98/boot2/boot.h
  stable/7/sys/boot/pc98/boot2/boot2.S
  stable/7/sys/boot/pc98/boot2/dinode.h
  stable/7/sys/boot/pc98/boot2/disk.c
  stable/7/sys/boot/pc98/boot2/fs.h
  stable/7/sys/boot/pc98/boot2/inode.h
  stable/7/sys/boot/pc98/boot2/io.c
  stable/7/sys/boot/pc98/boot2/probe_keyboard.c
  stable/7/sys/boot/pc98/boot2/quota.h
  stable/7/sys/boot/pc98/boot2/serial.S
  stable/7/sys/boot/pc98/boot2/serial_16550.S
  stable/7/sys/boot/pc98/boot2/serial_8251.S
  stable/7/sys/boot/pc98/boot2/start.S
  stable/7/sys/boot/pc98/boot2/sys.c
  stable/7/sys/boot/pc98/boot2/table.c
Modified:
  stable/7/sys/boot/pc98/boot2/Makefile
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/boot/pc98/boot2/Makefile
==============================================================================
--- stable/7/sys/boot/pc98/boot2/Makefile	Fri Jan 15 12:42:35 2010	(r202354)
+++ stable/7/sys/boot/pc98/boot2/Makefile	Fri Jan 15 12:45:23 2010	(r202355)
@@ -1,114 +1,104 @@
 # $FreeBSD$
-#
 
-PROG=	boot
-# Order is very important on the SRCS line for this prog
-SRCS=	start.S table.c boot2.S boot.c asm.S bios.S serial.S
-SRCS+=	probe_keyboard.c io.c disk.c sys.c
-
-BINMODE=	444
-CFLAGS=		-Os -mrtd \
-		-fno-guess-branch-probability \
-		-fno-unit-at-a-time \
-		-D_KERNEL -DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
-CFLAGS+=	-DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
-CFLAGS+=	${CWARNFLAGS}
-CFLAGS+=	-I${.CURDIR}/../../.. -I.
-
-# By default, if a serial port is going to be used as console, use COM1
-# (aka /dev/ttyd0).
-#BOOT_COMCONSOLE_PORT?=0x30
-BOOT_COMCONSOLE_PORT?=0x238
-BOOT_COMCONSOLE_CLK?=16
-BOOT_COMCONSOLE_MODE=0x0c
-CFLAGS+=	-DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
-		-DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \
-		-DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE}
-
-# feature not implemented
-BOOT_COMCONSOLE_SPEED?=9600
-CFLAGS+=	-DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
-
-# Enable code to take the default boot string from a fixed location on the
-# disk.  See nextboot(8) and README.386BSD for more info.
-#CFLAGS+=	-DNAMEBLOCK
-#CFLAGS+=	-DNAMEBLOCK_WRITEBACK
-
-# Bias the conversion from the BIOS drive number to the FreeBSD unit number
-# for hard disks.  This may be useful for people booting in a mixed IDE/SCSI
-# environment (set BOOT_HD_BIAS to the number of IDE drives).
-#CFLAGS+=	-DBOOT_HD_BIAS=1
-#
-# Details: this only applies if BOOT_HD_BIAS > 0.  If the BIOS drive number
-# for the boot drive is >= BOOT_HD_BIAS, then the boot drive is assumed to
-# be SCSI and have unit number (BIOS_drive_number - BOOT_HD_BIAS).  E.g.,
-# BOOT_HD_BIAS=1 makes BIOS drive 1 correspond to 1:da(0,a) instead of
-# 1:wd(1,a).  If `da' is given explicitly, then the drive is assumed to be
-# SCSI and have BIOS drive number (da_unit_number + BOOT_HD_BIAS).  E.g.,
-# BOOT_HD_BIAS=1 makes da(0,a) correspond to 1:da(0,a) instead of 0:da(0,a).
-
-CLEANFILES+=	boot.nohdr boot.strip boot.ldr boot1 boot2 sizetest
-LDFLAGS+=	-N -Ttext 0 -e start
-NO_SHARED=	YES
-NO_MAN=
-STRIP=
-
-# tunable timeout parameter, waiting for keypress, calibrated in ms
-BOOTWAIT?=	5000
-# tunable timeout during string input, calibrated in ms
-#TIMEOUT?=	30000
-
-# Location that boot2 is loaded at
-BOOTSEG=	0x1000
-
-# Offset in BOOTSEG for the top of the stack, keep this 16 byte aligned
-BOOTSTACK=	0xFFF0
-
-boot.nohdr:	boot
-	objcopy -S -O binary boot boot.nohdr
-	ls -l boot.nohdr
-
-boot.ldr:	boot.nohdr
-	dd if=boot.nohdr of=boot.ldr bs=8192 count=1 conv=sync
-
-boot1:		boot.nohdr
-	dd if=boot.nohdr of=boot1 bs=512 count=1
-
-boot2:		boot.nohdr
-	dd if=boot.nohdr of=boot2 bs=512 skip=1
-	@dd if=boot2 skip=14 of=sizetest 2> /dev/null
-	@if [ -s sizetest ] ; then \
-		echo "boot2 is too big" >&2 ; \
-		rm boot2 ; \
-		exit 2 ; \
-	fi
-
-all:		boot.ldr boot1 boot2
-
-install:
-	${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
-		boot.ldr ${DESTDIR}${BINDIR}/boot
-	${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
-		boot1 boot2 ${DESTDIR}${BINDIR}
-
-# If it's not there, don't consider it a target
-.if exists(${.CURDIR}/../../../pc98/include)
-beforedepend ${OBJS}: machine
-
-machine:
-	ln -sf ${.CURDIR}/../../../pc98/include machine
-
-.endif
-
-.if exists(${.CURDIR}/../../../i386/include) 
-beforedepend ${OBJS}: i386
+FILES=		boot boot1 boot2
 
-i386:
-	ln -sf ${.CURDIR}/../../../i386/include i386
+NM?=		nm
 
-.endif
+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=	-Os \
+	-fno-guess-branch-probability \
+	-fomit-frame-pointer \
+	-fno-unit-at-a-time \
+	-mno-align-long-strings \
+	-mrtd \
+	-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
+	-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 --param max-inline-insns-single=100
+
+# Set machine type to PC98_SYSTEM_PARAMETER
+#CFLAGS+=	-DSET_MACHINE_TYPE
+
+# Initialize the bi_bios_geom using the BIOS geometry
+#CFLAGS+=	-DGET_BIOSGEOM
+
+LDFLAGS=-static -N --gc-sections
+
+# 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} ${LDFLAGS} -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} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC}
+
+boot2.o: 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}
 
-CLEANFILES+=	machine i386
-
-.include "${.CURDIR}/../../../conf/kern.mk"
 .include <bsd.prog.mk>

Copied: stable/7/sys/boot/pc98/boot2/boot1.S (from r201342, head/sys/boot/pc98/boot2/boot1.S)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/sys/boot/pc98/boot2/boot1.S	Fri Jan 15 12:45:23 2010	(r202355, copy of r201342, head/sys/boot/pc98/boot2/boot1.S)
@@ -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,%di
+		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

Copied: stable/7/sys/boot/pc98/boot2/boot2.c (from r201342, head/sys/boot/pc98/boot2/boot2.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/sys/boot/pc98/boot2/boot2.c	Fri Jan 15 12:45:23 2010	(r202355, copy of r201342, head/sys/boot/pc98/boot2/boot2.c)
@@ -0,0 +1,842 @@
+/*-
+ * 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 <machine/psl.h>
+
+#include <stdarg.h>
+
+#include <a.out.h>
+
+#include <btxv86.h>
+
+#include "boot2.h"
+#include "lib.h"
+
+#define IO_KEYBOARD	1
+#define IO_SERIAL	2
+
+#define SECOND		1	/* Circa that many ticks in a second. */
+
+#define RBX_ASKNAME	0x0	/* -a */
+#define RBX_SINGLE	0x1	/* -s */
+/* 0x2 is reserved for log2(RB_NOSYNC). */
+/* 0x3 is reserved for log2(RB_HALT). */
+/* 0x4 is reserved for log2(RB_INITNAME). */
+#define RBX_DFLTROOT	0x5	/* -r */
+#define RBX_KDB 	0x6	/* -d */
+/* 0x7 is reserved for log2(RB_RDONLY). */
+/* 0x8 is reserved for log2(RB_DUMP). */
+/* 0x9 is reserved for log2(RB_MINIROOT). */
+#define RBX_CONFIG	0xa	/* -c */
+#define RBX_VERBOSE	0xb	/* -v */
+#define RBX_SERIAL	0xc	/* -h */
+#define RBX_CDROM	0xd	/* -C */
+/* 0xe is reserved for log2(RB_POWEROFF). */
+#define RBX_GDB 	0xf	/* -g */
+#define RBX_MUTE	0x10	/* -m */
+/* 0x11 is reserved for log2(RB_SELFTEST). */
+/* 0x12 is reserved for boot programs. */
+/* 0x13 is reserved for boot programs. */
+#define RBX_PAUSE	0x14	/* -p */
+#define RBX_QUIET	0x15	/* -q */
+#define RBX_NOINTR	0x1c	/* -n */
+/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
+#define RBX_DUAL	0x1d	/* -D */
+/* 0x1f is reserved for log2(RB_BOOTINFO). */
+
+/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
+#define RBX_MASK	(OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
+			OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
+			OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
+			OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
+			OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
+			OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
+
+#define PATH_CONFIG	"/boot.config"
+#define PATH_BOOT3	"/boot/loader"
+#define PATH_KERNEL	"/boot/kernel/kernel"
+
+#define ARGS		0x900
+#define NOPT		14
+#define NDEV		3
+#define V86_CY(x)	((x) & PSL_C)
+#define V86_ZR(x)	((x) & PSL_Z)
+
+#define DRV_DISK	0xf0
+#define DRV_UNIT	0x0f
+
+#define TYPE_AD		0
+#define TYPE_DA		1
+#define TYPE_FD		2
+
+#define OPT_SET(opt)	(1 << (opt))
+#define OPT_CHECK(opt)	((opts) & OPT_SET(opt))
+
+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;
+    unsigned slice;
+    unsigned part;
+    unsigned start;
+} dsk;
+static char cmd[512], cmddup[512];
+static char kname[1024];
+static uint32_t opts;
+static int comspeed = SIOSPD;
+static struct bootinfo bootinfo;
+static uint8_t ioctrl = IO_KEYBOARD;
+
+void exit(int);
+static void load(void);
+static int parse(void);
+static int xfsread(ino_t, void *, size_t);
+static int dskread(void *, unsigned, unsigned);
+static void printf(const char *,...);
+static void putchar(int);
+static uint32_t memsize(void);
+static int drvread(void *, unsigned);
+static int keyhit(unsigned);
+static int xputc(int);
+static int xgetc(int);
+static 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(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 uint32_t
+memsize(void)
+{
+    u_char *p = (u_char *)PTOV(0);
+
+    return *(p + 0x401) * 128 * 1024 + *(u_int16_t *)(p + 0x594) * 1024 * 1024;
+}
+
+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.efl & 0x1)
+	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, DOSBBSECTOR + 1))
+	return (WHOLE_DISK_SLICE);	/* Read error */
+    dp = (void *)(sec + DOSPARTOFF);
+    for (i = 0; i < NDOSPART; 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
+    int autoboot;
+    ino_t ino;
+
+    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;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list