xref: /csrg-svn/sys/i386/stand/fdbootblk.c (revision 48820)
1*48820Swilliam /*-
2*48820Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*48820Swilliam  * All rights reserved.
4*48820Swilliam  *
5*48820Swilliam  * This code is derived from software contributed to Berkeley by
6*48820Swilliam  * William Jolitz.
7*48820Swilliam  *
8*48820Swilliam  * %sccs.include.redist.c%
9*48820Swilliam  *
10*48820Swilliam  *	@(#)fdbootblk.c	7.1 (Berkeley) 04/28/91
11*48820Swilliam  */
12*48820Swilliam 
13*48820Swilliam /*
14*48820Swilliam  * fdbootblk.s:
15*48820Swilliam  *	Written 10/6/90 by William F. Jolitz
16*48820Swilliam  *	Initial block boot for AT/386 with typical stupid NEC controller
17*48820Swilliam  *	Works only with 3.5 inch diskettes that have 16 or greater sectors/side
18*48820Swilliam  *
19*48820Swilliam  *	Goal is to read in sucessive 7.5Kbytes of bootstrap to
20*48820Swilliam  *	execute.
21*48820Swilliam  *
22*48820Swilliam  *	No attempt is made to handle disk errors.
23*48820Swilliam  */
24*48820Swilliam /*#include "/sys/i386/isa/isa.h"
25*48820Swilliam #include "/sys/i386/isa/fdreg.h"*/
26*48820Swilliam #define	NOP	jmp 1f ; nop ; 1:
27*48820Swilliam #define BIOSRELOC	0x7c00
28*48820Swilliam #define	start	0x70400
29*48820Swilliam 
30*48820Swilliam 	/* step 0 force descriptors to bottom of address space */
31*48820Swilliam 
32*48820Swilliam 	.byte 0xfa,0xb8,0x30,0x00,0x8e,0xd0,0xbc,0x00,0x01 #ll fb
33*48820Swilliam 
34*48820Swilliam 	xorl	%eax,%eax
35*48820Swilliam 	movl	%ax,%ds
36*48820Swilliam 	movl	%ax,%es
37*48820Swilliam 
38*48820Swilliam 	/* step 1 load new descriptor table */
39*48820Swilliam 
40*48820Swilliam 	.byte 0x2E,0x0F,1,0x16
41*48820Swilliam 	.word	BIOSRELOC+0x4a	#GDTptr
42*48820Swilliam 	# word aword cs lgdt GDTptr
43*48820Swilliam 
44*48820Swilliam 	/* step 2 turn on protected mode */
45*48820Swilliam 
46*48820Swilliam 	smsw	%ax
47*48820Swilliam 	orb	$1,%al
48*48820Swilliam 	lmsw	%ax
49*48820Swilliam 	jmp	1f
50*48820Swilliam 	nop
51*48820Swilliam 
52*48820Swilliam 	/* step 3  reload segment descriptors */
53*48820Swilliam 
54*48820Swilliam  1:
55*48820Swilliam 	xorl	%eax,%eax
56*48820Swilliam 	movb	$0x10,%al
57*48820Swilliam 	movl	%ax,%ds
58*48820Swilliam 	movl	%ax,%es
59*48820Swilliam 	movl	%ax,%ss
60*48820Swilliam 	word
61*48820Swilliam 	ljmp	$0x8,$ BIOSRELOC+0x59	/* would be nice if .-RELOC+0x7c00 worked */
62*48820Swilliam 
63*48820Swilliam  /* Global Descriptor Table contains three descriptors:
64*48820Swilliam   * 0x00: Null: not used
65*48820Swilliam   * 0x08: Code: code segment starts at 0 and extents for 4 gigabytes
66*48820Swilliam   * 0x10: Data: data segment starts at 0 and extends for 4 gigabytes
67*48820Swilliam   *		(overlays code)
68*48820Swilliam   */
69*48820Swilliam GDT:
70*48820Swilliam NullDesc:	.word	0,0,0,0	# null descriptor - not used
71*48820Swilliam CodeDesc:	.word	0xFFFF	# limit at maximum: (bits 15:0)
72*48820Swilliam 	.byte	0,0,0	# base at 0: (bits 23:0)
73*48820Swilliam 	.byte	0x9f	# present/priv level 0/code/conforming/readable
74*48820Swilliam 	.byte	0xcf	# page granular/default 32-bit/limit(bits 19:16)
75*48820Swilliam 	.byte	0	# base at 0: (bits 31:24)
76*48820Swilliam DataDesc:	.word	0xFFFF	# limit at maximum: (bits 15:0)
77*48820Swilliam 	.byte	0,0,0	# base at 0: (bits 23:0)
78*48820Swilliam 	.byte	0x93	# present/priv level 0/data/expand-up/writeable
79*48820Swilliam 	.byte	0xcf	# page granular/default 32-bit/limit(bits 19:16)
80*48820Swilliam 	.byte	0	# base at 0: (bits 31:24)
81*48820Swilliam 
82*48820Swilliam /* Global Descriptor Table pointer
83*48820Swilliam  *  contains 6-byte pointer information for LGDT
84*48820Swilliam  */
85*48820Swilliam GDTptr:	.word	0x17	# limit to three 8 byte selectors(null,code,data)
86*48820Swilliam 	.long 	BIOSRELOC+0x32	# GDT -- arrgh, gas again!
87*48820Swilliam readcmd: .byte 0xe6,0,0,0,0,2,18,0x1b,0xff
88*48820Swilliam 
89*48820Swilliam 	/* step 4 relocate to final bootstrap address. */
90*48820Swilliam reloc:
91*48820Swilliam 	movl	$ BIOSRELOC,%esi
92*48820Swilliam 	movl	$ RELOC,%edi
93*48820Swilliam 	movl	$512,%ecx
94*48820Swilliam 	rep
95*48820Swilliam 	movsb
96*48820Swilliam 	pushl	$dodisk
97*48820Swilliam 	ret
98*48820Swilliam 
99*48820Swilliam 	/* step 5 load remaining 15 sectors off disk */
100*48820Swilliam dodisk:
101*48820Swilliam 	movl	$0x70200,%edi
102*48820Swilliam 	xorl	%ebx,%ebx
103*48820Swilliam 	incb	%bl
104*48820Swilliam 	incb	%bl
105*48820Swilliam #ifdef notdef
106*48820Swilliam 	movb	$0x11,%al
107*48820Swilliam 	outb	%al,$0x20
108*48820Swilliam 	NOP
109*48820Swilliam 	movb	$32,%al
110*48820Swilliam 	outb	%al,$0x21
111*48820Swilliam 	NOP
112*48820Swilliam 	movb	$4,%al
113*48820Swilliam 	outb	%al,$0x21
114*48820Swilliam 	NOP
115*48820Swilliam 	movb	$1,%al
116*48820Swilliam 	outb	%al,$0x21
117*48820Swilliam 	NOP
118*48820Swilliam #endif
119*48820Swilliam 	movb	$0x20,%al	# do a eoi
120*48820Swilliam 	outb	%al,$0x20
121*48820Swilliam 
122*48820Swilliam 	NOP
123*48820Swilliam 	movb	$0x07,%al
124*48820Swilliam 	outb	%al,$0x21
125*48820Swilliam 	NOP
126*48820Swilliam  8:
127*48820Swilliam 	movb	%bl,readcmd+4
128*48820Swilliam 	movl	%edi,%ecx
129*48820Swilliam 
130*48820Swilliam 	/* Set read/write bytes */
131*48820Swilliam 	xorl	%edx,%edx
132*48820Swilliam 	movb	$0x0c,%dl	# outb(0xC,0x46); outb(0xB,0x46);
133*48820Swilliam 	movb	$0x46,%al
134*48820Swilliam 	outb	%al,%dx
135*48820Swilliam 	NOP
136*48820Swilliam 	decb	%dx
137*48820Swilliam 	outb	%al,%dx
138*48820Swilliam 
139*48820Swilliam 	/* Send start address */
140*48820Swilliam 	movb	$0x04,%dl	# outb(0x4, addr);
141*48820Swilliam 	movb	%cl,%al
142*48820Swilliam 	outb	%al,%dx
143*48820Swilliam 	NOP
144*48820Swilliam 	movb	%ch,%al		# outb(0x4, addr>>8);
145*48820Swilliam 	outb	%al,%dx
146*48820Swilliam 	NOP
147*48820Swilliam 	rorl	$8,%ecx		# outb(0x81, addr>>16);
148*48820Swilliam 	movb	%ch,%al
149*48820Swilliam 	outb	%al,$0x81
150*48820Swilliam 	NOP
151*48820Swilliam 
152*48820Swilliam 	/* Send count */
153*48820Swilliam 	movb	$0x05,%dl	# outb(0x5, 0);
154*48820Swilliam 	xorl	%eax,%eax
155*48820Swilliam 	outb	%al,%dx
156*48820Swilliam 	NOP
157*48820Swilliam 	movb	$2,%al		# outb(0x5,2);
158*48820Swilliam 	outb	%al,%dx
159*48820Swilliam 	NOP
160*48820Swilliam 
161*48820Swilliam 	/* set channel 2 */
162*48820Swilliam 	# movb	$2,%al		# outb(0x0A,2);
163*48820Swilliam 	outb	%al,$0x0A
164*48820Swilliam 	NOP
165*48820Swilliam 
166*48820Swilliam 	/* issue read command to fdc */
167*48820Swilliam 	movw	$0x3f4,%dx
168*48820Swilliam 	movl	$readcmd,%esi
169*48820Swilliam 	xorl	%ecx,%ecx
170*48820Swilliam 	movb	$9,%cl
171*48820Swilliam 
172*48820Swilliam  2:	inb	%dx,%al
173*48820Swilliam 	NOP
174*48820Swilliam 	testb	$0x80,%al
175*48820Swilliam 	jz 2b
176*48820Swilliam 
177*48820Swilliam 	incb	%dx
178*48820Swilliam 	movl	(%esi),%al
179*48820Swilliam 	outb	%al,%dx
180*48820Swilliam 	NOP
181*48820Swilliam 	incl	%esi
182*48820Swilliam 	decb	%dx
183*48820Swilliam 	loop	 2b
184*48820Swilliam 
185*48820Swilliam 	/* watch the icu looking for an interrupt signalling completion */
186*48820Swilliam 	xorl	%edx,%edx
187*48820Swilliam 	movb	$0x20,%dl
188*48820Swilliam  2:	movb	$0xc,%al
189*48820Swilliam 	outb	%al,%dx
190*48820Swilliam 	NOP
191*48820Swilliam 	inb	%dx,%al
192*48820Swilliam 	NOP
193*48820Swilliam #ifdef notdef
194*48820Swilliam 	call	px
195*48820Swilliam #endif
196*48820Swilliam 	andb	$0x7f,%al
197*48820Swilliam 	cmpb	$6,%al
198*48820Swilliam 	jne	2b
199*48820Swilliam 	movb	$0x20,%al	# do a eoi
200*48820Swilliam 	outb	%al,%dx
201*48820Swilliam 	NOP
202*48820Swilliam 
203*48820Swilliam 	movl	$0x3f4,%edx
204*48820Swilliam 	xorl	%ecx,%ecx
205*48820Swilliam 	movb	$7,%cl
206*48820Swilliam  2:	inb	%dx,%al
207*48820Swilliam 	NOP
208*48820Swilliam 	andb	$0xC0,%al
209*48820Swilliam 	cmpb	$0xc0,%al
210*48820Swilliam 	jne	2b
211*48820Swilliam 	incb	%dx
212*48820Swilliam 	inb	%dx,%al
213*48820Swilliam 	decb	%dx
214*48820Swilliam 	loop	2b
215*48820Swilliam 
216*48820Swilliam #ifdef notdef
217*48820Swilliam 	inb	$0x61,%al
218*48820Swilliam 	NOP
219*48820Swilliam 	orb	$3,%al
220*48820Swilliam 	outb	%al,$0x61
221*48820Swilliam 	NOP
222*48820Swilliam #endif
223*48820Swilliam 
224*48820Swilliam 	/* extract the status bytes after the read. must we do this? */
225*48820Swilliam 	addw	$0x200,%edi	# next addr to load to
226*48820Swilliam 	incb	%bl
227*48820Swilliam #ifdef notdef
228*48820Swilliam  movb %bl,%al
229*48820Swilliam  call px
230*48820Swilliam #endif
231*48820Swilliam 	cmpb	$16,%bl
232*48820Swilliam 	jle	8b
233*48820Swilliam 
234*48820Swilliam 	/* for clever bootstrap, dig out boot unit and cylinder */
235*48820Swilliam 	pushl	$0
236*48820Swilliam 	pushl	$0
237*48820Swilliam 
238*48820Swilliam 	/* fd controller is major device 2 */
239*48820Swilliam 	pushl	$2	/* dev */
240*48820Swilliam 
241*48820Swilliam 	/* sorry, no flags at this point! */
242*48820Swilliam 
243*48820Swilliam 	pushl $	start
244*48820Swilliam 	ret	/* main (dev, unit, off) */
245*48820Swilliam 
246*48820Swilliam #ifdef notdef
247*48820Swilliam hextab:	.ascii	"0123456789abcdef"
248*48820Swilliam curs:	.long	0xb8000
249*48820Swilliam kbc:	.byte 0
250*48820Swilliam 
251*48820Swilliam px:
252*48820Swilliam 	pushal
253*48820Swilliam 	movl	curs,%edi
254*48820Swilliam 	movl	%eax,%ebx
255*48820Swilliam 	call	phd
256*48820Swilliam 	movl	%ebx,%eax
257*48820Swilliam 	shrl	$4,%eax
258*48820Swilliam 	call	phd
259*48820Swilliam 	movb	$0xe,%ah
260*48820Swilliam 	movb	$32,%al
261*48820Swilliam 	movw	%ax,(%edi)
262*48820Swilliam 	# movw	$(0xe<<8)+' ',(%edi)
263*48820Swilliam 	incl	%edi
264*48820Swilliam 	incl	%edi
265*48820Swilliam 	movl	%edi,curs
266*48820Swilliam 
267*48820Swilliam 2:	inb	$0x60,%al
268*48820Swilliam 	NOP
269*48820Swilliam 	cmpb	%al,kbc
270*48820Swilliam 	je	2b
271*48820Swilliam 	movb	%al,kbc
272*48820Swilliam 
273*48820Swilliam 	popal
274*48820Swilliam 	ret
275*48820Swilliam 
276*48820Swilliam phd:
277*48820Swilliam 	andl	$0xf,%eax
278*48820Swilliam 	movb	hextab(%eax),%al
279*48820Swilliam 	movb	$0xe,%ah
280*48820Swilliam 	movw	%ax,(%edi)
281*48820Swilliam 	incl	%edi
282*48820Swilliam 	incl	%edi
283*48820Swilliam 	ret
284*48820Swilliam #endif
285*48820Swilliam 
286*48820Swilliam ebootblkcode:
287*48820Swilliam 
288*48820Swilliam 	/* remaining space usable for a disk label */
289*48820Swilliam 
290*48820Swilliam 	.space	510-310		/* would be nice if .space 512-2-. worked */
291*48820Swilliam 	.word	0xaa55		/* signature -- used by BIOS ROM */
292*48820Swilliam 
293*48820Swilliam ebootblk: 			/* MUST BE EXACTLY 0x200 BIG FOR SURE */
294