xref: /csrg-svn/sys/i386/stand/fdbootblk.c (revision 63368)
148820Swilliam /*-
2*63368Sbostic  * Copyright (c) 1990, 1993
3*63368Sbostic  *	The Regents of the University of California.  All rights reserved.
448820Swilliam  *
548820Swilliam  * This code is derived from software contributed to Berkeley by
648820Swilliam  * William Jolitz.
748820Swilliam  *
848820Swilliam  * %sccs.include.redist.c%
948820Swilliam  *
10*63368Sbostic  *	@(#)fdbootblk.c	8.1 (Berkeley) 06/11/93
1148820Swilliam  */
1248820Swilliam 
1348820Swilliam /*
1452351Sbostic  * Initial block boot for AT/386 with typical stupid NEC controller.  Works
1552351Sbostic  * only with 3.5 inch diskettes that have 16 or greater sectors/side.  Goal
1652351Sbostic  * is to read in sucessive 7.5Kbytes of bootstrap to execute.  No attempt
1752351Sbostic  * is made to handle disk errors.
1848820Swilliam  */
1952351Sbostic #define	NOP		jmp 1f ; nop ; 1:
2052351Sbostic #define	BIOSRELOC	0x7c00
2152351Sbostic #define	start		0x70400
2248820Swilliam 
2352351Sbostic /* Gas does not know about 16 bit opcodes... */
2452351Sbostic 
2548820Swilliam 	/* step 0 force descriptors to bottom of address space */
2648820Swilliam 
2752351Sbostic 	.byte 	0xfa			# cli
2852351Sbostic 	.byte 	0xb8, 0x30, 0x00	# mov $0x0030, %ax
2952351Sbostic 	.byte 	0x8e, 0xd0 		# mov %ax, %ss
3052351Sbostic 	.byte 	0xbc, 0x00, 0x01  	# mov $0x0100, %sp
3148820Swilliam 
3248820Swilliam 	xorl	%eax,%eax
3348820Swilliam 	movl	%ax,%ds
3448820Swilliam 	movl	%ax,%es
3548820Swilliam 
3648820Swilliam 	/* step 1 load new descriptor table */
3748820Swilliam 
3852351Sbostic 	.byte 	0x2e			# seg cs
3952351Sbostic 	.byte 	0x0f, 0x01, 0x16	# lgdt DS:d16
4052351Sbostic 	.word	BIOSRELOC + 0x4a	# [BIOSRELOC + GDTptr]
4148820Swilliam 
4248820Swilliam 	/* step 2 turn on protected mode */
4348820Swilliam 
4448820Swilliam 	smsw	%ax
4548820Swilliam 	orb	$1,%al
4648820Swilliam 	lmsw	%ax
4748820Swilliam 	jmp	1f
4848820Swilliam 	nop
4948820Swilliam 
5052351Sbostic  1:
5148820Swilliam 	/* step 3  reload segment descriptors */
5248820Swilliam 
5348820Swilliam 	xorl	%eax,%eax
5448820Swilliam 	movb	$0x10,%al
5548820Swilliam 	movl	%ax,%ds
5648820Swilliam 	movl	%ax,%es
5748820Swilliam 	movl	%ax,%ss
5848820Swilliam 	word
5952351Sbostic 	ljmp	$0x8, $ BIOSRELOC + 0x59 # [BIOSRELOC + reloc]
6048820Swilliam 
6152351Sbostic  /*
6252351Sbostic   * Global Descriptor Table contains three descriptors:
6348820Swilliam   * 0x00: Null: not used
6448820Swilliam   * 0x08: Code: code segment starts at 0 and extents for 4 gigabytes
6548820Swilliam   * 0x10: Data: data segment starts at 0 and extends for 4 gigabytes
6648820Swilliam   *		(overlays code)
6748820Swilliam   */
6848820Swilliam GDT:
6952351Sbostic NullDsc:.word	0,0,0,0	# null descriptor - not used
7052351Sbostic CodeDsc:.word	0xFFFF	# limit at maximum: (bits 15:0)
7148820Swilliam 	.byte	0,0,0	# base at 0: (bits 23:0)
7248820Swilliam 	.byte	0x9f	# present/priv level 0/code/conforming/readable
7348820Swilliam 	.byte	0xcf	# page granular/default 32-bit/limit(bits 19:16)
7448820Swilliam 	.byte	0	# base at 0: (bits 31:24)
7552351Sbostic DataDsc:.word	0xFFFF	# limit at maximum: (bits 15:0)
7648820Swilliam 	.byte	0,0,0	# base at 0: (bits 23:0)
7748820Swilliam 	.byte	0x93	# present/priv level 0/data/expand-up/writeable
7848820Swilliam 	.byte	0xcf	# page granular/default 32-bit/limit(bits 19:16)
7948820Swilliam 	.byte	0	# base at 0: (bits 31:24)
8048820Swilliam 
8152351Sbostic /*
8252351Sbostic  * Global Descriptor Table pointer
8348820Swilliam  *  contains 6-byte pointer information for LGDT
8448820Swilliam  */
8548820Swilliam GDTptr:	.word	0x17	# limit to three 8 byte selectors(null,code,data)
8652351Sbostic 	.long 	BIOSRELOC + 0x32	# [BIOSRELOC + GDT]
8748820Swilliam 
8852351Sbostic readcmd: .byte 0xe6, 0x00, 0x00, 0x00, 0x00, 0x02, 18, 0x1b, 0xff
8952351Sbostic 
9048820Swilliam 	/* step 4 relocate to final bootstrap address. */
9148820Swilliam reloc:
9248820Swilliam 	movl	$ BIOSRELOC,%esi
9348820Swilliam 	movl	$ RELOC,%edi
9448820Swilliam 	movl	$512,%ecx
9548820Swilliam 	rep
9648820Swilliam 	movsb
9748820Swilliam 	pushl	$dodisk
9848820Swilliam 	ret
9948820Swilliam 
10048820Swilliam 	/* step 5 load remaining 15 sectors off disk */
10148820Swilliam dodisk:
10248820Swilliam 	movl	$0x70200,%edi
10348820Swilliam 	xorl	%ebx,%ebx
10448820Swilliam 	incb	%bl
10548820Swilliam 	incb	%bl
10648820Swilliam 	movb	$0x20,%al	# do a eoi
10748820Swilliam 	outb	%al,$0x20
10848820Swilliam 
10948820Swilliam 	NOP
11048820Swilliam 	movb	$0x07,%al
11148820Swilliam 	outb	%al,$0x21
11248820Swilliam 	NOP
11348820Swilliam  8:
11448820Swilliam 	movb	%bl,readcmd+4
11548820Swilliam 	movl	%edi,%ecx
11648820Swilliam 
11748820Swilliam 	/* Set read/write bytes */
11848820Swilliam 	xorl	%edx,%edx
11948820Swilliam 	movb	$0x0c,%dl	# outb(0xC,0x46); outb(0xB,0x46);
12048820Swilliam 	movb	$0x46,%al
12148820Swilliam 	outb	%al,%dx
12248820Swilliam 	NOP
12348820Swilliam 	decb	%dx
12448820Swilliam 	outb	%al,%dx
12548820Swilliam 
12648820Swilliam 	/* Send start address */
12748820Swilliam 	movb	$0x04,%dl	# outb(0x4, addr);
12848820Swilliam 	movb	%cl,%al
12948820Swilliam 	outb	%al,%dx
13048820Swilliam 	NOP
13148820Swilliam 	movb	%ch,%al		# outb(0x4, addr>>8);
13248820Swilliam 	outb	%al,%dx
13348820Swilliam 	NOP
13448820Swilliam 	rorl	$8,%ecx		# outb(0x81, addr>>16);
13548820Swilliam 	movb	%ch,%al
13648820Swilliam 	outb	%al,$0x81
13748820Swilliam 	NOP
13848820Swilliam 
13948820Swilliam 	/* Send count */
14048820Swilliam 	movb	$0x05,%dl	# outb(0x5, 0);
14148820Swilliam 	xorl	%eax,%eax
14248820Swilliam 	outb	%al,%dx
14348820Swilliam 	NOP
14448820Swilliam 	movb	$2,%al		# outb(0x5,2);
14548820Swilliam 	outb	%al,%dx
14648820Swilliam 	NOP
14748820Swilliam 
14848820Swilliam 	/* set channel 2 */
14948820Swilliam 	# movb	$2,%al		# outb(0x0A,2);
15048820Swilliam 	outb	%al,$0x0A
15148820Swilliam 	NOP
15248820Swilliam 
15348820Swilliam 	/* issue read command to fdc */
15448820Swilliam 	movw	$0x3f4,%dx
15548820Swilliam 	movl	$readcmd,%esi
15648820Swilliam 	xorl	%ecx,%ecx
15748820Swilliam 	movb	$9,%cl
15848820Swilliam 
15948820Swilliam  2:	inb	%dx,%al
16048820Swilliam 	NOP
16148820Swilliam 	testb	$0x80,%al
16248820Swilliam 	jz 2b
16348820Swilliam 
16448820Swilliam 	incb	%dx
16548820Swilliam 	movl	(%esi),%al
16648820Swilliam 	outb	%al,%dx
16748820Swilliam 	NOP
16848820Swilliam 	incl	%esi
16948820Swilliam 	decb	%dx
17048820Swilliam 	loop	 2b
17148820Swilliam 
17248820Swilliam 	/* watch the icu looking for an interrupt signalling completion */
17348820Swilliam 	xorl	%edx,%edx
17448820Swilliam 	movb	$0x20,%dl
17548820Swilliam  2:	movb	$0xc,%al
17648820Swilliam 	outb	%al,%dx
17748820Swilliam 	NOP
17848820Swilliam 	inb	%dx,%al
17948820Swilliam 	NOP
18048820Swilliam 	andb	$0x7f,%al
18148820Swilliam 	cmpb	$6,%al
18248820Swilliam 	jne	2b
18348820Swilliam 	movb	$0x20,%al	# do a eoi
18448820Swilliam 	outb	%al,%dx
18548820Swilliam 	NOP
18648820Swilliam 
18748820Swilliam 	movl	$0x3f4,%edx
18848820Swilliam 	xorl	%ecx,%ecx
18948820Swilliam 	movb	$7,%cl
19048820Swilliam  2:	inb	%dx,%al
19148820Swilliam 	NOP
19248820Swilliam 	andb	$0xC0,%al
19348820Swilliam 	cmpb	$0xc0,%al
19448820Swilliam 	jne	2b
19548820Swilliam 	incb	%dx
19648820Swilliam 	inb	%dx,%al
19748820Swilliam 	decb	%dx
19848820Swilliam 	loop	2b
19948820Swilliam 
20048820Swilliam 	/* extract the status bytes after the read. must we do this? */
20148820Swilliam 	addw	$0x200,%edi	# next addr to load to
20248820Swilliam 	incb	%bl
20348820Swilliam 	cmpb	$16,%bl
20448820Swilliam 	jle	8b
20548820Swilliam 
20648820Swilliam 	/* for clever bootstrap, dig out boot unit and cylinder */
20748820Swilliam 	pushl	$0
20848820Swilliam 	pushl	$0
20948820Swilliam 
21048820Swilliam 	/* fd controller is major device 2 */
21148820Swilliam 	pushl	$2	/* dev */
21248820Swilliam 
21348820Swilliam 	/* sorry, no flags at this point! */
21448820Swilliam 
21548820Swilliam 	pushl $	start
21648820Swilliam 	ret	/* main (dev, unit, off) */
21748820Swilliam 
21848820Swilliam ebootblkcode:
21948820Swilliam 
22048820Swilliam 	/* remaining space usable for a disk label */
22148820Swilliam 
22248820Swilliam 	.space	510-310		/* would be nice if .space 512-2-. worked */
22348820Swilliam 	.word	0xaa55		/* signature -- used by BIOS ROM */
22448820Swilliam 
22548820Swilliam ebootblk: 			/* MUST BE EXACTLY 0x200 BIG FOR SURE */
226