xref: /netbsd-src/sys/arch/i386/stand/lib/bios_disk.S (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1/*	$NetBSD: bios_disk.S,v 1.18 2005/12/11 12:17:48 christos 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	xorl	%eax, %eax
86	movw	%bx, %ax	# return value in %ax
87
88	pop	%edi
89	pop	%edx
90	popl	%ebx
91	popl	%ebp
92	ret
93
94/*
95 * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
96 *	Call with	%ah = 0x2
97 *			%al = number of sectors
98 *			%ch = cylinder
99 *			%cl = sector
100 *			%dh = head
101 *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
102 *			%es:%bx = segment:offset of buffer
103 *	Return:
104 *			%al = 0x0 on success; err code on failure
105 *
106 * biosdisk_read(dev, cyl, head, sect, count, buff_addr);
107 *
108 *  Note: On failure, you must reset the disk with biosdisk_reset() before
109 *        sending another command.
110 */
111ENTRY(biosdisk_read)
112	pushl	%ebp
113	movl	%esp, %ebp
114	pushl	%ebx
115	push	%ecx
116	push	%edx
117	push	%esi
118	push	%edi
119
120	movb	16(%ebp), %dh
121	movw	12(%ebp), %cx
122	xchgb	%ch, %cl	# cylinder; the highest 2 bits of cyl is in %cl
123	rorb	$2, %cl
124	movb	20(%ebp), %al
125	orb	%al, %cl
126	incb	%cl		# sector; sec starts from 1, not 0
127	movb	8(%ebp), %dl	# device
128	movl	28(%ebp), %ebx	# buffer address (may be >64k)
129	movb	24(%ebp), %al	# number of sectors
130
131	call	_C_LABEL(prot_to_real)	# enter real mode
132	.code16
133
134	push	%bx
135	shrl	$4, %ebx	# max segment
136	mov	%ds, %si
137	add	%si, %bx
138	mov	%bx, %es	# %es:%bx now valid buffer address
139	pop	%bx
140	and	$0xf, %bx	# and min offset - to avoid overrun
141
142	movb	$0x2, %ah	# subfunction
143	int	$0x13
144	setc	%al		# error code is in %ah
145
146	calll	_C_LABEL(real_to_prot) # back to protected mode
147	.code32
148
149	andl	$0xffff, %eax
150
151	pop	%edi
152	pop	%esi
153	pop	%edx
154	pop	%ecx
155	popl	%ebx
156	popl	%ebp
157	ret
158
159/*
160 * biosdisk_getinfo(int dev):  return a word that represents the
161 *	max number of sectors, heads and cylinders for this device
162 */
163ENTRY(biosdisk_getinfo)
164	pushl	%ebp
165	movl	%esp, %ebp
166	push	%es
167	pushl	%ebx
168	push	%ecx
169	push	%edx
170	push	%esi
171	push	%edi
172
173	movb	8(%ebp), %dl		# diskinfo(drive #)
174
175	call	_C_LABEL(prot_to_real)	# enter real mode
176	.code16
177
178	push	%dx			# save drive #
179	movb	$0x08, %ah		# ask for disk info
180	int	$0x13
181	pop	%bx			# restore drive #
182	jnc	ok
183
184	testb	$0x80, %bl		# is it a hard disk?
185	jnz	ok
186
187	/*
188	 * Urk.  Call failed.  It is not supported for floppies by old BIOS's.
189	 * Guess it's a 15-sector floppy.  Initialize all the registers for
190	 * documentation, although we only need head and sector counts.
191	 */
192	xorw	%ax, %ax		# set status to success
193#	movb	%ah, %bh		# %bh = 0
194#	movb	$2, %bl			# %bl bits 0-3 = drive type, 2 = 1.2M
195	movb	$79, %ch		# max track
196	movb	$15, %cl		# max sector
197	movb	$1, %dh			# max head
198#	movb	$1, %dl			# # floppy drives installed
199	# es:di = parameter table
200	# carry = 0
201
202ok:
203	calll	_C_LABEL(real_to_prot)	# back to protected mode
204	.code32
205
206	/* form a longword representing all this gunk */
207	shrl	$8, %eax		# clear unnecessary bits
208	shll	$24, %eax
209	shll	$16, %ecx		# do the same for %ecx
210	shrl	$8, %ecx
211	movb	%dh, %cl		# max head
212	orl	%ecx, %eax		# return value in %eax
213
214	pop	%edi
215	pop	%esi
216	pop	%edx
217	pop	%ecx
218	popl	%ebx
219	pop	%es
220	popl	%ebp
221	ret
222
223/*
224 * int biosdisk_int13ext(int dev):
225 *	check for availibility of int13 extensions.
226 */
227ENTRY(biosdisk_int13ext)
228	pushl	%ebp
229	movl	%esp, %ebp
230	pushl	%ebx
231	pushl	%ecx
232	pushl	%edx
233	pushl	%esi
234	pushl	%edi
235
236	movb	8(%ebp), %dl		# drive #
237	movw	$0x55aa, %bx
238
239	call	_C_LABEL(prot_to_real)	# enter real mode
240	.code16
241
242	movb	$0x41, %ah		# ask for disk info
243	int	$0x13
244	setnc	%dl
245
246	calll	_C_LABEL(real_to_prot)	# switch back
247	.code32
248
249	xorl	%eax, %eax
250	movb	%dl, %al	# return value in %ax
251
252	cmpw	$0xaa55, %bx
253	sete	%dl
254	andb	%dl, %al
255
256	andb	%cl, %al
257
258	popl	%edi
259	popl	%esi
260	popl	%edx
261	popl	%ecx
262	popl	%ebx
263	popl	%ebp
264	ret
265
266/*
267 * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
268 *	Call with	%ah = 0x42
269 *			%ds:%si = parameter block (data buffer address
270 *				must be a real mode physical address).
271 *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
272 *	Return:
273 *			%al = 0x0 on success; err code on failure
274 */
275ENTRY(biosdisk_extread)
276	pushl	%ebp
277	movl	%esp, %ebp
278	pushl	%ebx
279	push	%ecx
280	push	%edx
281	push	%esi
282	push	%edi
283
284	movb	8(%ebp), %dl	# device
285	movl	12(%ebp), %esi	# parameter block
286
287	call	_C_LABEL(prot_to_real)	# enter real mode
288	.code16
289
290	movl	%esi, %eax
291	shrl	$4, %eax
292	movw	%ds, %bx
293	addw	%bx, %ax
294	movw	%ax, %ds
295	andw	$0xf, %si
296
297	movb	$0x42, %ah	# subfunction
298	int	$0x13
299	setc	%bl
300	movb	%ah, %bh	# save error code
301
302	calll	_C_LABEL(real_to_prot) # back to protected mode
303	.code32
304
305	xorl	%eax, %eax
306	movw	%bx, %ax	# return value in %ax
307
308	pop	%edi
309	pop	%esi
310	pop	%edx
311	pop	%ecx
312	popl	%ebx
313	popl	%ebp
314	ret
315
316ENTRY(biosdisk_getextinfo)
317	pushl	%ebp
318	movl	%esp, %ebp
319	pushl	%ebx
320	push	%ecx
321	push	%edx
322	push	%esi
323	push	%edi
324
325	movb	8(%ebp), %dl	# device
326	movl	12(%ebp), %esi	# parameter block
327
328	call	_C_LABEL(prot_to_real)	# enter real mode
329	.code16
330
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
342	calll	_C_LABEL(real_to_prot) # back to protected mode
343	.code32
344
345	xorl	%eax, %eax
346	movb	%bl, %al	# return value in %ax
347
348	pop	%edi
349	pop	%esi
350	pop	%edx
351	pop	%ecx
352	popl	%ebx
353	popl	%ebp
354	ret
355