xref: /titanic_41/usr/src/psm/stand/bootblks/ufs/i386/mboot.S (revision 9b79392525856301c6f8962f189c2a32242af618)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate/*
23*9b793925STheo Schlossnagle * Copyright 2012 OmniTI Computer Consulting, Inc.  All rights reserved.
24*9b793925STheo Schlossnagle *
257c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
267c478bd9Sstevel@tonic-gate * Use is subject to license terms.
277c478bd9Sstevel@tonic-gate */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate/*
307c478bd9Sstevel@tonic-gate * SOLARIS MASTER BOOT:
317c478bd9Sstevel@tonic-gate *
327c478bd9Sstevel@tonic-gate * PURPOSE: loads the primary boot from the active fdisk partition.
337c478bd9Sstevel@tonic-gate *          in effect, this routine mimics the functionality of INT 0x19.
347c478bd9Sstevel@tonic-gate *
357c478bd9Sstevel@tonic-gate * resides on the first physical sector of the hard drive media.
367c478bd9Sstevel@tonic-gate * loaded by INT 0x19 (ROM bootstrap loader) at address 0x7C00
377c478bd9Sstevel@tonic-gate * limited to 512 bytes total, including embedded fdisk table.
387c478bd9Sstevel@tonic-gate *
397c478bd9Sstevel@tonic-gate * for compatibility with the ROM BIOS, we contain standard DOS structures:
407c478bd9Sstevel@tonic-gate *
417c478bd9Sstevel@tonic-gate *	the fdisk partition table (at offset 0x1BE-0x1FE)
427c478bd9Sstevel@tonic-gate *	boot signature bytes (0x55, 0xAA at 0x1FE, 0x1FF)
437c478bd9Sstevel@tonic-gate *
447c478bd9Sstevel@tonic-gate * the above two entities are required in order to be compatible with
457c478bd9Sstevel@tonic-gate * the manner in which the DOS BIOS has always performed its boot operation.
467c478bd9Sstevel@tonic-gate * In the event that our master boot record is inadvertently replaced by
477c478bd9Sstevel@tonic-gate * a standard DOS boot sector, the booting operation will still succeed!
487c478bd9Sstevel@tonic-gate *
497c478bd9Sstevel@tonic-gate * This master boot record uses the relsect/numsect fields of the partition
507c478bd9Sstevel@tonic-gate * table entry, to compute the start of the active partition; therefore,
517c478bd9Sstevel@tonic-gate * it is geometry independent.  This means that the drive could be "built"
527c478bd9Sstevel@tonic-gate * on a system with a disk controller that uses a given disk geometry, but
537c478bd9Sstevel@tonic-gate * would run on any other controller.
547c478bd9Sstevel@tonic-gate *
557c478bd9Sstevel@tonic-gate * SYNOPSIS:
567c478bd9Sstevel@tonic-gate *     begins execution at 0:0x7C00
577c478bd9Sstevel@tonic-gate *     relocates to 0:0x600 (to get out of the way!)
587c478bd9Sstevel@tonic-gate *     reads fdisk table to locate bootable partition
597c478bd9Sstevel@tonic-gate *     load boot record from the active fdisk partition at 0x7C00
607c478bd9Sstevel@tonic-gate *     verify boot record signature bytes
617c478bd9Sstevel@tonic-gate *     jump to/execute the SOLARIS PARTITION PRIMARY BOOT
627c478bd9Sstevel@tonic-gate *     error handler - can either reboot, or invoke INT 0x18.
637c478bd9Sstevel@tonic-gate *
647c478bd9Sstevel@tonic-gate * interface from DOS INT 0x19:  BootDev in DL
657c478bd9Sstevel@tonic-gate * (this fails sometimes, so we look for a signature to determine whether
667c478bd9Sstevel@tonic-gate *  to rely on DL from the floppy boot, or if we should assume 0x80 from
677c478bd9Sstevel@tonic-gate *  the BIOS)
687c478bd9Sstevel@tonic-gate *
697c478bd9Sstevel@tonic-gate * interface to partition boot: BootDev in DL
707c478bd9Sstevel@tonic-gate *
717c478bd9Sstevel@tonic-gate *=============================================================================
727c478bd9Sstevel@tonic-gate * Master boot record: resides on first physical sector of device
737c478bd9Sstevel@tonic-gate */
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate/*
767c478bd9Sstevel@tonic-gate * This file is written in GNU as syntax using Intel assembler syntax.  The
777c478bd9Sstevel@tonic-gate * startup label _start will be executed at address PBOOT_ADDR (0x7C00), but
787c478bd9Sstevel@tonic-gate * the text section must be set at address RELOC_ADDR (0x600).  With GNU ld
797c478bd9Sstevel@tonic-gate * this can be done using the "-Ttext 600" option.
807c478bd9Sstevel@tonic-gate */
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate#define	PBOOT_ADDR	0x7C00
847c478bd9Sstevel@tonic-gate#define	RELOC_ADDR	0x600
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate#define	FDISK_START	0x1BE
877c478bd9Sstevel@tonic-gate#define	BOOT_SIG	0xAA55
887c478bd9Sstevel@tonic-gate#define	N_RETRIES	5
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate#define	FD_NUMPART	4
917c478bd9Sstevel@tonic-gate#define	FD_PTESIZE	0x10
927c478bd9Sstevel@tonic-gate#define	ACTIVE		0x80
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate/*
957c478bd9Sstevel@tonic-gate * A convenience macro for declaring a message string (using .ascii directive--
967c478bd9Sstevel@tonic-gate * NOT nul-terminated) surrounded by two labels, which can then be used with
977c478bd9Sstevel@tonic-gate * the SIZEOF() macro to get its length.
987c478bd9Sstevel@tonic-gate */
997c478bd9Sstevel@tonic-gate#define	MSG(label, string)	label: .ascii string; label##_end:
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate/*
1027c478bd9Sstevel@tonic-gate * Returns the length of some consecutive bytes.  These bytes must be placed
1037c478bd9Sstevel@tonic-gate * between two labels.  The ending label must be the same as the starting label
1047c478bd9Sstevel@tonic-gate * but with a suffix "_end".
1057c478bd9Sstevel@tonic-gate */
106*9b793925STheo Schlossnagle#define	SIZEOF(label)	(label##_end - label)
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate	.title	"Solaris_Master_Boot"
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate	.intel_syntax noprefix		/* use Intel syntax */
1127c478bd9Sstevel@tonic-gate	.code16				/* 16-bit mode (real mode) */
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate	.text				/* code segment begins here */
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate	.global	BootDev
1177c478bd9Sstevel@tonic-gate	.global _start
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate_start:					/* _start is loaded at PBOOT_ADDR */
1207c478bd9Sstevel@tonic-gate	jmp	bootrun
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gateVersion:
1237c478bd9Sstevel@tonic-gate	.ascii	"M3.0"			/* ident string */
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gatebootrun:
1267c478bd9Sstevel@tonic-gate	cli				/* don't bother me now! */
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate	/* prepare to relocate ourselves */
1297c478bd9Sstevel@tonic-gate	cld				/* prepare for relocation */
1307c478bd9Sstevel@tonic-gate	mov	si, PBOOT_ADDR
1317c478bd9Sstevel@tonic-gate	mov	di, RELOC_ADDR
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate	/* set up segment registers */
1347c478bd9Sstevel@tonic-gate	mov	ax, cs			/* initialize segment registers */
1357c478bd9Sstevel@tonic-gate	mov	ss, ax
1367c478bd9Sstevel@tonic-gate	mov	sp, si			/* stack starts down from 7C00 */
1377c478bd9Sstevel@tonic-gate	mov	es, ax
1387c478bd9Sstevel@tonic-gate	mov	ds, ax
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate	push	cx 			/* save possible signature on stack */
1417c478bd9Sstevel@tonic-gate	mov	cx, 0x100
1427c478bd9Sstevel@tonic-gate	rep	movsw
1437c478bd9Sstevel@tonic-gate	pop	cx			/* restore saved cx */
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate	/* running at PBOOT_ADDR, jump to RELOC_ADDR-rel addr */
1467c478bd9Sstevel@tonic-gate	jmp	(new_home - PBOOT_ADDR + RELOC_ADDR)
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gatenew_home:
1497c478bd9Sstevel@tonic-gate	sti				/* re-enable interrupts */
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate	/*
1527c478bd9Sstevel@tonic-gate	 * assuming boot device number is in dl has caused problems in the past
1537c478bd9Sstevel@tonic-gate	 * since we still don't absolutely have to rely on it, I've just
1547c478bd9Sstevel@tonic-gate	 * removed the now-pointless code to check for the FACE-CAFE signature
1557c478bd9Sstevel@tonic-gate	 * from mdexec, which doesn't do anything anymore, but left the
1567c478bd9Sstevel@tonic-gate	 * assumption that BootDev is 0x80 and nothing but.  If we ever need to
1577c478bd9Sstevel@tonic-gate	 * have BIOS load us from a drive not numbered 0x80, we'll need to
1587c478bd9Sstevel@tonic-gate	 * uncomment the following line; otherwise, the initialized value of
1597c478bd9Sstevel@tonic-gate	 * BootDev, namely 0x80, will be used for disk accesses.
1607c478bd9Sstevel@tonic-gate	 */
1617c478bd9Sstevel@tonic-gate	/* mov BootDev, dl */
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate	/* set debug flag based on seeing "both shift down" */
1647c478bd9Sstevel@tonic-gate	mov	ah, 2		/* get shift state */
1657c478bd9Sstevel@tonic-gate	int	0x16
1667c478bd9Sstevel@tonic-gate	and	al, 3		/* isolate shift-key bits */
1677c478bd9Sstevel@tonic-gate	cmp	al, 3
1687c478bd9Sstevel@tonic-gate	jne	nodbg
1697c478bd9Sstevel@tonic-gate	mov	byte ptr [debugmode], 1		/* set to 1 */
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gatenodbg:
1727c478bd9Sstevel@tonic-gate	/*
1737c478bd9Sstevel@tonic-gate	 * Search the fdisk table sequentially to find a physical partition
1747c478bd9Sstevel@tonic-gate	 * that is marked as "active" (bootable).
1757c478bd9Sstevel@tonic-gate	 */
1767c478bd9Sstevel@tonic-gate	mov	bx, RELOC_ADDR + FDISK_START
1777c478bd9Sstevel@tonic-gate	mov	cx, FD_NUMPART
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gatenxtpart:
1807c478bd9Sstevel@tonic-gate	cmp	byte ptr [bx], ACTIVE
1817c478bd9Sstevel@tonic-gate	je	got_active_part
1827c478bd9Sstevel@tonic-gate	add	bx, FD_PTESIZE
1837c478bd9Sstevel@tonic-gate	loop	nxtpart
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gatenoparts:
1867c478bd9Sstevel@tonic-gate	mov	bp, offset NoActiveErrMsg
1877c478bd9Sstevel@tonic-gate	mov	cx, SIZEOF(NoActiveErrMsg)
1887c478bd9Sstevel@tonic-gate	jmp	fatal_err
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gategot_active_part:
1917c478bd9Sstevel@tonic-gate	mov	ah, 0		/* reset disk */
1927c478bd9Sstevel@tonic-gate	int	0x13
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate	push	bx		/* save partition pointer */
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate	/* Check for LBA BIOS */
1977c478bd9Sstevel@tonic-gate	mov	ah, 0x41	/* chkext function */
1987c478bd9Sstevel@tonic-gate	mov	bx, 0x55AA	/* signature to change */
1997c478bd9Sstevel@tonic-gate	mov	cx, 0
2007c478bd9Sstevel@tonic-gate	int	0x13
2017c478bd9Sstevel@tonic-gate	jc	noLBA		/* carry == failure */
2027c478bd9Sstevel@tonic-gate	cmp	bx, 0xAA55
2037c478bd9Sstevel@tonic-gate	jne	noLBA		/* bad signature in BX == failure */
2047c478bd9Sstevel@tonic-gate	test	cx, 1		/* cx & 1 must be true, or... */
2057c478bd9Sstevel@tonic-gate	jz	noLBA		/* ...no LBA */
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate	mov	bp, offset lbastring
2087c478bd9Sstevel@tonic-gate	mov	cx, SIZEOF(lbastring)
2097c478bd9Sstevel@tonic-gate	call	debugout
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate	/*
2127c478bd9Sstevel@tonic-gate	 * LBA case: form a packet on the stack and call fn 0x42 to read
2137c478bd9Sstevel@tonic-gate	 * packet, backwards (from hi to lo addresses):
2147c478bd9Sstevel@tonic-gate	 * 8-byte LBA
2157c478bd9Sstevel@tonic-gate	 * seg:ofs buffer address
2167c478bd9Sstevel@tonic-gate	 * byte reserved
2177c478bd9Sstevel@tonic-gate	 * byte nblocks
2187c478bd9Sstevel@tonic-gate	 * byte reserved
2197c478bd9Sstevel@tonic-gate	 * packet size in bytes (>= 0x10)
2207c478bd9Sstevel@tonic-gate	 */
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate	pop	bx		/* restore partition pointer */
2237c478bd9Sstevel@tonic-gate	push	bx		/* and save again */
2247c478bd9Sstevel@tonic-gate	mov	cx, N_RETRIES	/* retry count */
2257c478bd9Sstevel@tonic-gateretryLBA:
2267c478bd9Sstevel@tonic-gate	pushd	0		/* hi 32 bits of 64-bit sector number */
2277c478bd9Sstevel@tonic-gate	push	dword ptr [bx+8]	/* relsect (lo 32 of 64-bit number) */
2287c478bd9Sstevel@tonic-gate	push	dword ptr [solaris_priboot]	/* seg:ofs of buffer */
2297c478bd9Sstevel@tonic-gate	push	1		/* reserved, one block */
2307c478bd9Sstevel@tonic-gate	push	0x10		/* reserved, size (0x10) */
2317c478bd9Sstevel@tonic-gate	mov	ah, 0x42	/* "read LBA" */
2327c478bd9Sstevel@tonic-gate	mov	si, sp		/* (ds already == ss) */
2337c478bd9Sstevel@tonic-gate	int	0x13
2347c478bd9Sstevel@tonic-gate	lahf			/* save flags */
2357c478bd9Sstevel@tonic-gate	add	sp, 16		/* restore stack */
2367c478bd9Sstevel@tonic-gate	sahf			/* restore flags */
2377c478bd9Sstevel@tonic-gate	jnc	readok		/* got it */
2387c478bd9Sstevel@tonic-gate	mov	ah, 0		/* reset disk */
2397c478bd9Sstevel@tonic-gate	int	0x13
2407c478bd9Sstevel@tonic-gate	loop	retryLBA	/* try again */
2417c478bd9Sstevel@tonic-gate	jmp	readerr		/* exhausted retries; give up */
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gatenoLBA:
2447c478bd9Sstevel@tonic-gate	mov	bp, offset chsstring
2457c478bd9Sstevel@tonic-gate	mov	cx, SIZEOF(chsstring)
2467c478bd9Sstevel@tonic-gate	call	debugout
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate	pop	bx		/* restore partition pointer */
2497c478bd9Sstevel@tonic-gate	push	bx		/* and save again */
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate	/* get BIOS disk parameters */
2527c478bd9Sstevel@tonic-gate	mov	dl, byte ptr [BootDev]
2537c478bd9Sstevel@tonic-gate	mov	ah, 0x8
2547c478bd9Sstevel@tonic-gate	int	0x13
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate	jnc	geomok
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate	/* error reading geom; die */
2597c478bd9Sstevel@tonic-gate	mov	bp, offset GeomErrMsg
2607c478bd9Sstevel@tonic-gate	mov	cx, SIZEOF(GeomErrMsg)
2617c478bd9Sstevel@tonic-gate	jmp	fatal_err
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gategeomok:
2647c478bd9Sstevel@tonic-gate	/* calculate sectors per track */
2657c478bd9Sstevel@tonic-gate	mov	al, cl		/* ah doesn't matter; mul dh will set it */
2667c478bd9Sstevel@tonic-gate	and	al, 0x3F
2677c478bd9Sstevel@tonic-gate	mov	byte ptr [secPerTrk], al
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate	/* calculate sectors per cylinder */
2707c478bd9Sstevel@tonic-gate	inc	dh
2717c478bd9Sstevel@tonic-gate	mul	dh
2727c478bd9Sstevel@tonic-gate	mov	word ptr [secPerCyl], ax
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate	/* calculate cylinder # */
2757c478bd9Sstevel@tonic-gate	mov	ax, [bx+8]	/* ax = loword(relsect) */
2767c478bd9Sstevel@tonic-gate	mov	dx, [bx+10]	/* dx:ax = relsect */
2777c478bd9Sstevel@tonic-gate	div	word ptr [secPerCyl]	/* ax = cyl, */
2787c478bd9Sstevel@tonic-gate					/* dx = sect in cyl (0 - cylsize-1) */
2797c478bd9Sstevel@tonic-gate	mov	bx, ax		/* bx = cyl */
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate	/* calculate head/sector # */
2827c478bd9Sstevel@tonic-gate	mov	ax, dx		/* ax = sect in cyl (0 - cylsize-1) */
2837c478bd9Sstevel@tonic-gate	div	byte ptr [secPerTrk]	/* al = head, */
2847c478bd9Sstevel@tonic-gate					/* ah = 0-rel sect in track */
2857c478bd9Sstevel@tonic-gate	inc	ah		/* ah = 1-rel sector */
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate	xor	cl,cl		/* cl = 0 */
2887c478bd9Sstevel@tonic-gate	mov	ch, bh		/* ch = hi bits of cyl (if any) */
2897c478bd9Sstevel@tonic-gate	shr	cx, 2		/* cl{7:6} = cyl{9:8} (if any) */
2907c478bd9Sstevel@tonic-gate	and	cl, 0xC0	/* cl = cyl{9:8} to merge with sect (if any) */
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate	or	cl, ah		/* cl{7:6} = cyl bits, cl{5:0} = sect */
2937c478bd9Sstevel@tonic-gate	mov	ch, bl		/* ch = lo cyl bits */
2947c478bd9Sstevel@tonic-gate	mov	dh, al		/* dh = head */
2957c478bd9Sstevel@tonic-gate	mov	dl, byte ptr [BootDev]		/* dl = drivenum */
2967c478bd9Sstevel@tonic-gate	les	bx, solaris_priboot		/* es:bx points to buffer */
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate	mov	si, N_RETRIES
2997c478bd9Sstevel@tonic-gateretry_noLBA:
3007c478bd9Sstevel@tonic-gate	mov	ax, 0x201	/* 02=read, sector count = 1 */
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate	int	0x13
3037c478bd9Sstevel@tonic-gate	jnc	readok
3047c478bd9Sstevel@tonic-gate	mov	ah, 0		/* reset disk */
3057c478bd9Sstevel@tonic-gate	int	0x13
3067c478bd9Sstevel@tonic-gate	dec	si
3077c478bd9Sstevel@tonic-gate	cmp	si, 0
3087c478bd9Sstevel@tonic-gate	jne	retry_noLBA	/* retry, or fall through to read error */
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gatereaderr:
3117c478bd9Sstevel@tonic-gate	mov	bp, offset ReadErrMsg
3127c478bd9Sstevel@tonic-gate	mov	cx, SIZEOF(ReadErrMsg)
3137c478bd9Sstevel@tonic-gate	jmp	fatal_err
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gatereadok:
3167c478bd9Sstevel@tonic-gate	/* verify boot record signature */
3177c478bd9Sstevel@tonic-gate	mov	bx, PBOOT_ADDR
3187c478bd9Sstevel@tonic-gate	cmp	word ptr [bx+0x1FE], BOOT_SIG
3197c478bd9Sstevel@tonic-gate	je	sigok
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate	mov	bp, offset SigErrMsg
3227c478bd9Sstevel@tonic-gate	mov	cx, SIZEOF(SigErrMsg)
3237c478bd9Sstevel@tonic-gate	jmp	fatal_err
3247c478bd9Sstevel@tonic-gate
3257c478bd9Sstevel@tonic-gatesigok:
3267c478bd9Sstevel@tonic-gate	mov	dl, byte ptr [BootDev]	/* pass BootDev to next boot phase */
3277c478bd9Sstevel@tonic-gate	pop	si			/* and pass partition pointer ds:si */
3287c478bd9Sstevel@tonic-gate	call	dword ptr [solaris_priboot]	/* call doesn't return! */
3297c478bd9Sstevel@tonic-gate
3307c478bd9Sstevel@tonic-gate	mov	bp, offset ReturnErrMsg
3317c478bd9Sstevel@tonic-gate	mov	cx, SIZEOF(ReturnErrMsg)
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gatefatal_err:			/* land of no return....... */
3347c478bd9Sstevel@tonic-gate	/*
3357c478bd9Sstevel@tonic-gate	 * bp contains pointer to error message string,
3367c478bd9Sstevel@tonic-gate	 * cx contains string length
3377c478bd9Sstevel@tonic-gate	 */
3387c478bd9Sstevel@tonic-gate	mov	bx, 0x4F	/* video page, attribute */
3397c478bd9Sstevel@tonic-gate	call	msgout
3407c478bd9Sstevel@tonic-gate	int	0x18
3417c478bd9Sstevel@tonic-gate
3427c478bd9Sstevel@tonic-gatedebugout:
3437c478bd9Sstevel@tonic-gate	/* call with string pointer in es:bp, len in cx */
3447c478bd9Sstevel@tonic-gate	cmp	byte ptr [debugmode], 0
3457c478bd9Sstevel@tonic-gate	je	debugout_ret	/* skip if not in debug mode */
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate	mov	bx, 0x1F	/* page, attr (white on blue) */
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate	/* alternate entry for fatal_err */
3507c478bd9Sstevel@tonic-gatemsgout:
3517c478bd9Sstevel@tonic-gate	pusha
3527c478bd9Sstevel@tonic-gate	mov	ax, 0x1301
3537c478bd9Sstevel@tonic-gate	mov	dx, 0x1700	/* row, col */
3547c478bd9Sstevel@tonic-gate	int	0x10
3557c478bd9Sstevel@tonic-gate
3567c478bd9Sstevel@tonic-gate	mov	al, 7		/* BEL */
3577c478bd9Sstevel@tonic-gate	mov	cx, 1
3587c478bd9Sstevel@tonic-gate	int	0x10
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate	mov	ah, 0		/* get key */
3617c478bd9Sstevel@tonic-gate	int	0x16
3627c478bd9Sstevel@tonic-gate	popa
3637c478bd9Sstevel@tonic-gate
3647c478bd9Sstevel@tonic-gatedebugout_ret:
3657c478bd9Sstevel@tonic-gate	ret
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gatesecPerTrk:
3687c478bd9Sstevel@tonic-gate	.byte	0
3697c478bd9Sstevel@tonic-gatesecPerCyl:
3707c478bd9Sstevel@tonic-gate	.word	0
3717c478bd9Sstevel@tonic-gatesolaris_priboot:
3727c478bd9Sstevel@tonic-gate	.long	PBOOT_ADDR
3737c478bd9Sstevel@tonic-gateBootDev:
3747c478bd9Sstevel@tonic-gate	.byte	0x80		/* assumes drive 80 (see comment above) */
3757c478bd9Sstevel@tonic-gatedebugmode:
3767c478bd9Sstevel@tonic-gate	.byte	0
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gateMSG(GeomErrMsg,		"Can't read geometry")
3797c478bd9Sstevel@tonic-gateMSG(NoActiveErrMsg,	"No active partition")
3807c478bd9Sstevel@tonic-gateMSG(ReadErrMsg,		"Can't read PBR")
3817c478bd9Sstevel@tonic-gateMSG(SigErrMsg,		"Bad PBR sig")
3827c478bd9Sstevel@tonic-gateMSG(ReturnErrMsg,	"!!!")
3837c478bd9Sstevel@tonic-gateMSG(lbastring,		"LBA")
3847c478bd9Sstevel@tonic-gateMSG(chsstring,		"CHS")
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate/*
3877c478bd9Sstevel@tonic-gate * For debugging:  Here's a representative FDISK table entry
3887c478bd9Sstevel@tonic-gate *
3897c478bd9Sstevel@tonic-gate * .org   0x1BE
3907c478bd9Sstevel@tonic-gate * .byte  0x80,1,1,0,0x82,0xfe,0x7f,4,0x3f,0,0,0,0x86,0xfa,0x3f,0
3917c478bd9Sstevel@tonic-gate */
3927c478bd9Sstevel@tonic-gate	.org 	0x1FE
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate	.word	BOOT_SIG
395