bios_disk.S revision 1.20 1 1.20 jakllsch /* $NetBSD: bios_disk.S,v 1.20 2010/12/29 22:40:46 jakllsch 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.17 junyoung ENTRY(biosdisk_reset)
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.20 jakllsch movzwl %bx, %eax # return value in %eax
86 1.9 dyoung
87 1.9 dyoung pop %edi
88 1.9 dyoung pop %edx
89 1.9 dyoung popl %ebx
90 1.9 dyoung popl %ebp
91 1.9 dyoung ret
92 1.9 dyoung
93 1.9 dyoung /*
94 1.15 junyoung * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
95 1.15 junyoung * Call with %ah = 0x2
96 1.15 junyoung * %al = number of sectors
97 1.15 junyoung * %ch = cylinder
98 1.15 junyoung * %cl = sector
99 1.15 junyoung * %dh = head
100 1.15 junyoung * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
101 1.15 junyoung * %es:%bx = segment:offset of buffer
102 1.15 junyoung * Return:
103 1.15 junyoung * %al = 0x0 on success; err code on failure
104 1.15 junyoung *
105 1.17 junyoung * biosdisk_read(dev, cyl, head, sect, count, buff_addr);
106 1.15 junyoung *
107 1.17 junyoung * Note: On failure, you must reset the disk with biosdisk_reset() before
108 1.15 junyoung * sending another command.
109 1.15 junyoung */
110 1.17 junyoung ENTRY(biosdisk_read)
111 1.1 perry pushl %ebp
112 1.1 perry movl %esp, %ebp
113 1.1 perry pushl %ebx
114 1.1 perry push %ecx
115 1.1 perry push %edx
116 1.1 perry push %esi
117 1.1 perry push %edi
118 1.1 perry
119 1.1 perry movb 16(%ebp), %dh
120 1.1 perry movw 12(%ebp), %cx
121 1.1 perry xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
122 1.1 perry rorb $2, %cl
123 1.1 perry movb 20(%ebp), %al
124 1.1 perry orb %al, %cl
125 1.1 perry incb %cl # sector; sec starts from 1, not 0
126 1.1 perry movb 8(%ebp), %dl # device
127 1.12 dsl movl 28(%ebp), %ebx # buffer address (may be >64k)
128 1.12 dsl movb 24(%ebp), %al # number of sectors
129 1.1 perry
130 1.1 perry call _C_LABEL(prot_to_real) # enter real mode
131 1.10 dsl .code16
132 1.10 dsl
133 1.12 dsl push %bx
134 1.12 dsl shrl $4, %ebx # max segment
135 1.10 dsl mov %ds, %si
136 1.12 dsl add %si, %bx
137 1.12 dsl mov %bx, %es # %es:%bx now valid buffer address
138 1.12 dsl pop %bx
139 1.12 dsl and $0xf, %bx # and min offset - to avoid overrun
140 1.1 perry
141 1.1 perry movb $0x2, %ah # subfunction
142 1.1 perry int $0x13
143 1.12 dsl setc %al # error code is in %ah
144 1.14 junyoung
145 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
146 1.10 dsl .code32
147 1.1 perry
148 1.20 jakllsch movzwl %ax, %eax # return value in %eax
149 1.1 perry
150 1.1 perry pop %edi
151 1.1 perry pop %esi
152 1.1 perry pop %edx
153 1.1 perry pop %ecx
154 1.1 perry popl %ebx
155 1.1 perry popl %ebp
156 1.1 perry ret
157 1.1 perry
158 1.1 perry /*
159 1.17 junyoung * biosdisk_getinfo(int dev): return a word that represents the
160 1.15 junyoung * max number of sectors, heads and cylinders for this device
161 1.15 junyoung */
162 1.17 junyoung ENTRY(biosdisk_getinfo)
163 1.1 perry pushl %ebp
164 1.1 perry movl %esp, %ebp
165 1.1 perry push %es
166 1.1 perry pushl %ebx
167 1.1 perry push %ecx
168 1.1 perry push %edx
169 1.1 perry push %esi
170 1.1 perry push %edi
171 1.1 perry
172 1.6 drochner movb 8(%ebp), %dl # diskinfo(drive #)
173 1.1 perry
174 1.1 perry call _C_LABEL(prot_to_real) # enter real mode
175 1.10 dsl .code16
176 1.1 perry
177 1.16 junyoung push %dx # save drive #
178 1.1 perry movb $0x08, %ah # ask for disk info
179 1.1 perry int $0x13
180 1.16 junyoung pop %bx # restore drive #
181 1.1 perry jnc ok
182 1.1 perry
183 1.16 junyoung testb $0x80, %bl # is it a hard disk?
184 1.16 junyoung jnz ok
185 1.16 junyoung
186 1.1 perry /*
187 1.1 perry * Urk. Call failed. It is not supported for floppies by old BIOS's.
188 1.1 perry * Guess it's a 15-sector floppy. Initialize all the registers for
189 1.1 perry * documentation, although we only need head and sector counts.
190 1.1 perry */
191 1.16 junyoung xorw %ax, %ax # set status to success
192 1.1 perry # movb %ah, %bh # %bh = 0
193 1.1 perry # movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
194 1.6 drochner movb $79, %ch # max track
195 1.1 perry movb $15, %cl # max sector
196 1.1 perry movb $1, %dh # max head
197 1.1 perry # movb $1, %dl # # floppy drives installed
198 1.1 perry # es:di = parameter table
199 1.1 perry # carry = 0
200 1.1 perry
201 1.1 perry ok:
202 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
203 1.10 dsl .code32
204 1.7 fvdl
205 1.6 drochner /* form a longword representing all this gunk */
206 1.16 junyoung shrl $8, %eax # clear unnecessary bits
207 1.16 junyoung shll $24, %eax
208 1.16 junyoung shll $16, %ecx # do the same for %ecx
209 1.16 junyoung shrl $8, %ecx
210 1.16 junyoung movb %dh, %cl # max head
211 1.16 junyoung orl %ecx, %eax # return value in %eax
212 1.1 perry
213 1.1 perry pop %edi
214 1.1 perry pop %esi
215 1.1 perry pop %edx
216 1.1 perry pop %ecx
217 1.1 perry popl %ebx
218 1.1 perry pop %es
219 1.2 ws popl %ebp
220 1.2 ws ret
221 1.2 ws
222 1.2 ws /*
223 1.17 junyoung * int biosdisk_int13ext(int dev):
224 1.17 junyoung * check for availibility of int13 extensions.
225 1.15 junyoung */
226 1.17 junyoung ENTRY(biosdisk_int13ext)
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.20 jakllsch movzbl %dl, %eax # return value in %eax
249 1.2 ws
250 1.2 ws cmpw $0xaa55, %bx
251 1.2 ws sete %dl
252 1.4 ws andb %dl, %al
253 1.2 ws
254 1.4 ws andb %cl, %al
255 1.2 ws
256 1.2 ws popl %edi
257 1.2 ws popl %esi
258 1.2 ws popl %edx
259 1.2 ws popl %ecx
260 1.2 ws popl %ebx
261 1.2 ws popl %ebp
262 1.2 ws ret
263 1.2 ws
264 1.2 ws /*
265 1.15 junyoung * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
266 1.15 junyoung * Call with %ah = 0x42
267 1.15 junyoung * %ds:%si = parameter block (data buffer address
268 1.15 junyoung * must be a real mode physical address).
269 1.15 junyoung * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
270 1.15 junyoung * Return:
271 1.15 junyoung * %al = 0x0 on success; err code on failure
272 1.15 junyoung */
273 1.17 junyoung ENTRY(biosdisk_extread)
274 1.2 ws pushl %ebp
275 1.2 ws movl %esp, %ebp
276 1.2 ws pushl %ebx
277 1.2 ws push %ecx
278 1.2 ws push %edx
279 1.2 ws push %esi
280 1.2 ws push %edi
281 1.2 ws
282 1.2 ws movb 8(%ebp), %dl # device
283 1.2 ws movl 12(%ebp), %esi # parameter block
284 1.2 ws
285 1.2 ws call _C_LABEL(prot_to_real) # enter real mode
286 1.10 dsl .code16
287 1.10 dsl
288 1.19 dsl push %ds
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.19 dsl pop %ds
301 1.5 fvdl
302 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
303 1.10 dsl .code32
304 1.5 fvdl
305 1.20 jakllsch movzwl %bx, %eax # return value in %eax
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.17 junyoung ENTRY(biosdisk_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.19 dsl push %ds
331 1.10 dsl movl %esi, %eax
332 1.10 dsl shrl $4, %eax
333 1.10 dsl andw $0xf, %si
334 1.10 dsl movw %ds, %bx
335 1.10 dsl addw %bx, %ax
336 1.10 dsl movw %ax, %ds
337 1.5 fvdl
338 1.5 fvdl movb $0x48, %ah # subfunction
339 1.2 ws int $0x13
340 1.2 ws setc %bl
341 1.19 dsl pop %ds
342 1.2 ws
343 1.10 dsl calll _C_LABEL(real_to_prot) # back to protected mode
344 1.10 dsl .code32
345 1.2 ws
346 1.20 jakllsch movzbl %bl, %eax # return value in %eax
347 1.2 ws
348 1.2 ws pop %edi
349 1.2 ws pop %esi
350 1.2 ws pop %edx
351 1.2 ws pop %ecx
352 1.2 ws popl %ebx
353 1.1 perry popl %ebp
354 1.1 perry ret
355