xref: /netbsd/sys/arch/i386/stand/lib/bios_disk.S (revision 6550d01e)
1/*	$NetBSD: bios_disk.S,v 1.20 2010/12/29 22:40:46 jakllsch Exp $	*/
2
3/*
4 * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
5 *
6 * Mach Operating System
7 * Copyright (c) 1992, 1991 Carnegie Mellon University
8 * All Rights Reserved.
9 *
10 * Permission to use, copy, modify and distribute this software and its
11 * documentation is hereby granted, provided that both the copyright
12 * notice and this permission notice appear in all copies of the
13 * software, derivative works or modified versions, and any portions
14 * thereof, and that both notices appear in supporting documentation.
15 *
16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23 *  School of Computer Science
24 *  Carnegie Mellon University
25 *  Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie Mellon
28 * the rights to redistribute these changes.
29 */
30
31/*
32  Copyright 1988, 1989, 1990, 1991, 1992
33   by Intel Corporation, Santa Clara, California.
34
35                All Rights Reserved
36
37Permission to use, copy, modify, and distribute this software and
38its documentation for any purpose and without fee is hereby
39granted, provided that the above copyright notice appears in all
40copies and that both the copyright notice and this permission notice
41appear in supporting documentation, and that the name of Intel
42not be used in advertising or publicity pertaining to distribution
43of the software without specific, written prior permission.
44
45INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
46INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
47IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
48CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
49LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
50NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
51WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
52*/
53
54/* extracted from netbsd:sys/arch/i386/boot/bios.S */
55
56#include <machine/asm.h>
57
58/*
59 * BIOS call "INT 0x13 Function 0x0" to reset the disk subsystem
60 *	Call with	%ah = 0x0
61 *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
62 *	Return:
63 *			%al = 0x0 on success; err code on failure
64 */
65ENTRY(biosdisk_reset)
66	pushl	%ebp
67	movl	%esp, %ebp
68	pushl	%ebx
69	push	%edx
70	push	%edi
71
72	movb	8(%ebp), %dl	# device
73
74	call	_C_LABEL(prot_to_real)	# enter real mode
75	.code16
76
77	movb	$0x0, %ah	# subfunction
78	int	$0x13
79	setc	%bl
80	movb	%ah, %bh	# save error code
81
82	calll	_C_LABEL(real_to_prot) # back to protected mode
83	.code32
84
85	movzwl	%bx, %eax	# return value in %eax
86
87	pop	%edi
88	pop	%edx
89	popl	%ebx
90	popl	%ebp
91	ret
92
93/*
94 * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
95 *	Call with	%ah = 0x2
96 *			%al = number of sectors
97 *			%ch = cylinder
98 *			%cl = sector
99 *			%dh = head
100 *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
101 *			%es:%bx = segment:offset of buffer
102 *	Return:
103 *			%al = 0x0 on success; err code on failure
104 *
105 * biosdisk_read(dev, cyl, head, sect, count, buff_addr);
106 *
107 *  Note: On failure, you must reset the disk with biosdisk_reset() before
108 *        sending another command.
109 */
110ENTRY(biosdisk_read)
111	pushl	%ebp
112	movl	%esp, %ebp
113	pushl	%ebx
114	push	%ecx
115	push	%edx
116	push	%esi
117	push	%edi
118
119	movb	16(%ebp), %dh
120	movw	12(%ebp), %cx
121	xchgb	%ch, %cl	# cylinder; the highest 2 bits of cyl is in %cl
122	rorb	$2, %cl
123	movb	20(%ebp), %al
124	orb	%al, %cl
125	incb	%cl		# sector; sec starts from 1, not 0
126	movb	8(%ebp), %dl	# device
127	movl	28(%ebp), %ebx	# buffer address (may be >64k)
128	movb	24(%ebp), %al	# number of sectors
129
130	call	_C_LABEL(prot_to_real)	# enter real mode
131	.code16
132
133	push	%bx
134	shrl	$4, %ebx	# max segment
135	mov	%ds, %si
136	add	%si, %bx
137	mov	%bx, %es	# %es:%bx now valid buffer address
138	pop	%bx
139	and	$0xf, %bx	# and min offset - to avoid overrun
140
141	movb	$0x2, %ah	# subfunction
142	int	$0x13
143	setc	%al		# error code is in %ah
144
145	calll	_C_LABEL(real_to_prot) # back to protected mode
146	.code32
147
148	movzwl	%ax, %eax	# return value in %eax
149
150	pop	%edi
151	pop	%esi
152	pop	%edx
153	pop	%ecx
154	popl	%ebx
155	popl	%ebp
156	ret
157
158/*
159 * biosdisk_getinfo(int dev):  return a word that represents the
160 *	max number of sectors, heads and cylinders for this device
161 */
162ENTRY(biosdisk_getinfo)
163	pushl	%ebp
164	movl	%esp, %ebp
165	push	%es
166	pushl	%ebx
167	push	%ecx
168	push	%edx
169	push	%esi
170	push	%edi
171
172	movb	8(%ebp), %dl		# diskinfo(drive #)
173
174	call	_C_LABEL(prot_to_real)	# enter real mode
175	.code16
176
177	push	%dx			# save drive #
178	movb	$0x08, %ah		# ask for disk info
179	int	$0x13
180	pop	%bx			# restore drive #
181	jnc	ok
182
183	testb	$0x80, %bl		# is it a hard disk?
184	jnz	ok
185
186	/*
187	 * Urk.  Call failed.  It is not supported for floppies by old BIOS's.
188	 * Guess it's a 15-sector floppy.  Initialize all the registers for
189	 * documentation, although we only need head and sector counts.
190	 */
191	xorw	%ax, %ax		# set status to success
192#	movb	%ah, %bh		# %bh = 0
193#	movb	$2, %bl			# %bl bits 0-3 = drive type, 2 = 1.2M
194	movb	$79, %ch		# max track
195	movb	$15, %cl		# max sector
196	movb	$1, %dh			# max head
197#	movb	$1, %dl			# # floppy drives installed
198	# es:di = parameter table
199	# carry = 0
200
201ok:
202	calll	_C_LABEL(real_to_prot)	# back to protected mode
203	.code32
204
205	/* form a longword representing all this gunk */
206	shrl	$8, %eax		# clear unnecessary bits
207	shll	$24, %eax
208	shll	$16, %ecx		# do the same for %ecx
209	shrl	$8, %ecx
210	movb	%dh, %cl		# max head
211	orl	%ecx, %eax		# return value in %eax
212
213	pop	%edi
214	pop	%esi
215	pop	%edx
216	pop	%ecx
217	popl	%ebx
218	pop	%es
219	popl	%ebp
220	ret
221
222/*
223 * int biosdisk_int13ext(int dev):
224 *	check for availibility of int13 extensions.
225 */
226ENTRY(biosdisk_int13ext)
227	pushl	%ebp
228	movl	%esp, %ebp
229	pushl	%ebx
230	pushl	%ecx
231	pushl	%edx
232	pushl	%esi
233	pushl	%edi
234
235	movb	8(%ebp), %dl		# drive #
236	movw	$0x55aa, %bx
237
238	call	_C_LABEL(prot_to_real)	# enter real mode
239	.code16
240
241	movb	$0x41, %ah		# ask for disk info
242	int	$0x13
243	setnc	%dl
244
245	calll	_C_LABEL(real_to_prot)	# switch back
246	.code32
247
248	movzbl	%dl, %eax		# return value in %eax
249
250	cmpw	$0xaa55, %bx
251	sete	%dl
252	andb	%dl, %al
253
254	andb	%cl, %al
255
256	popl	%edi
257	popl	%esi
258	popl	%edx
259	popl	%ecx
260	popl	%ebx
261	popl	%ebp
262	ret
263
264/*
265 * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
266 *	Call with	%ah = 0x42
267 *			%ds:%si = parameter block (data buffer address
268 *				must be a real mode physical address).
269 *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
270 *	Return:
271 *			%al = 0x0 on success; err code on failure
272 */
273ENTRY(biosdisk_extread)
274	pushl	%ebp
275	movl	%esp, %ebp
276	pushl	%ebx
277	push	%ecx
278	push	%edx
279	push	%esi
280	push	%edi
281
282	movb	8(%ebp), %dl	# device
283	movl	12(%ebp), %esi	# parameter block
284
285	call	_C_LABEL(prot_to_real)	# enter real mode
286	.code16
287
288	push	%ds
289	movl	%esi, %eax
290	shrl	$4, %eax
291	movw	%ds, %bx
292	addw	%bx, %ax
293	movw	%ax, %ds
294	andw	$0xf, %si
295
296	movb	$0x42, %ah	# subfunction
297	int	$0x13
298	setc	%bl
299	movb	%ah, %bh	# save error code
300	pop	%ds
301
302	calll	_C_LABEL(real_to_prot) # back to protected mode
303	.code32
304
305	movzwl	%bx, %eax	# return value in %eax
306
307	pop	%edi
308	pop	%esi
309	pop	%edx
310	pop	%ecx
311	popl	%ebx
312	popl	%ebp
313	ret
314
315ENTRY(biosdisk_getextinfo)
316	pushl	%ebp
317	movl	%esp, %ebp
318	pushl	%ebx
319	push	%ecx
320	push	%edx
321	push	%esi
322	push	%edi
323
324	movb	8(%ebp), %dl	# device
325	movl	12(%ebp), %esi	# parameter block
326
327	call	_C_LABEL(prot_to_real)	# enter real mode
328	.code16
329
330	push	%ds
331	movl	%esi, %eax
332	shrl	$4, %eax
333	andw	$0xf, %si
334	movw	%ds, %bx
335	addw	%bx, %ax
336	movw	%ax, %ds
337
338	movb	$0x48, %ah	# subfunction
339	int	$0x13
340	setc	%bl
341	pop	%ds
342
343	calll	_C_LABEL(real_to_prot) # back to protected mode
344	.code32
345
346	movzbl	%bl, %eax	# return value in %eax
347
348	pop	%edi
349	pop	%esi
350	pop	%edx
351	pop	%ecx
352	popl	%ebx
353	popl	%ebp
354	ret
355