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