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