Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / i386 / boot / biosboot / bios.S
1 /*
2  * Mach Operating System
3  * Copyright (c) 1992, 1991 Carnegie Mellon University
4  * All Rights Reserved.
5  * 
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  * 
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  * 
16  * Carnegie Mellon requests users of this software to return to
17  * 
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  * 
23  * any improvements or extensions that they make and grant Carnegie Mellon
24  * the rights to redistribute these changes.
25  *
26  *      from: Mach, Revision 2.2  92/04/04  11:34:26  rpd
27  * $FreeBSD: src/sys/i386/boot/biosboot/bios.S,v 1.15 1999/08/28 00:43:11 peter Exp $
28  */
29
30 /*
31   Copyright 1988, 1989, 1990, 1991, 1992 
32    by Intel Corporation, Santa Clara, California.
33
34                 All Rights Reserved
35
36 Permission to use, copy, modify, and distribute this software and
37 its documentation for any purpose and without fee is hereby
38 granted, provided that the above copyright notice appears in all
39 copies and that both the copyright notice and this permission notice
40 appear in supporting documentation, and that the name of Intel
41 not be used in advertising or publicity pertaining to distribution
42 of the software without specific, written prior permission.
43
44 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
45 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
46 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
47 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
48 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
49 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
50 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51 */
52
53 /*
54  * Extensions for El Torito CD-ROM booting:
55  *
56  * Copyright © 1997 Pluto Technologies International, Inc.  Boulder CO
57  * Copyright © 1997 interface business GmbH, Dresden.
58  *      All rights reserved.
59  *
60  * This code has been written by Jörg Wunsch, Dresden.
61  * Direct comments to <joerg_wunsch@interface-business.de>.
62  *
63  * Redistribution and use in source and binary forms, with or without
64  * modification, are permitted provided that the following conditions
65  * are met:
66  * 1. Redistributions of source code must retain the above copyright
67  *    notice, this list of conditions and the following disclaimer.
68  * 2. Redistributions in binary form must reproduce the above copyright
69  *    notice, this list of conditions and the following disclaimer in the
70  *    documentation and/or other materials provided with the distribution.
71  *
72  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
73  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
76  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
78  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
79  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
80  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
81  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
82  * POSSIBILITY OF SUCH DAMAGE.
83  *
84  */
85
86         .file   "bios.s"
87
88 #include "asm.h"
89         .text
90
91 #ifndef CDBOOT
92
93 /*
94  * biosread(dev, cyl, head, sec, nsec, offset)
95  *      Read "nsec" sectors from disk to offset "offset" in boot segment
96  * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
97  *      Call with       %ah = 0x2
98  *                      %al = number of sectors
99  *                      %ch = cylinder
100  *                      %cl = sector
101  *                      %dh = head
102  *                      %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
103  *                      %es:%bx = segment:offset of buffer
104  *      Return:         
105  *                      %al = 0x0 on success; err code on failure
106  */
107
108 ENTRY(biosread)
109         push    %ebp
110         mov     %esp, %ebp
111
112         push    %ebx
113         push    %esi
114         push    %edi
115
116         movb    0x10(%ebp), %dh
117         movw    0x0c(%ebp), %cx
118         /* cylinder; the highest 2 bits of cyl is in %cl */
119         xchgb   %ch, %cl
120         rorb    $2, %cl
121         movb    0x14(%ebp), %al
122         orb     %al, %cl
123         incb    %cl                     /* sector; sec starts from 1, not 0 */
124         movb    0x8(%ebp), %dl          /* device */
125         movl    0x1c(%ebp), %ebx        /* offset */
126
127         /* prot_to_real will set %es to BOOTSEG */
128         call    EXT(prot_to_real)       /* enter real mode */
129         movb    $0x2, %ah               /* subfunction */
130         addr32
131         movb    0x18(%ebp), %al         /* number of sectors */
132
133         sti
134         int     $0x13
135         cli
136
137         /* save return value (actually movw %ax, %bx) */
138         mov     %eax, %ebx
139
140         data32
141         call    EXT(real_to_prot)       /* back to protected mode */
142
143         xor     %eax, %eax
144         movb    %bh, %al                /* return value in %ax */
145
146         pop     %edi
147         pop     %esi
148         pop     %ebx
149         pop     %ebp
150
151         ret
152
153 #else /* CDBOOT */
154
155
156 /*
157  * int
158  * getbootspec(struct specpacket *offset)
159  *
160  * Read CD-ROM boot specification packet to "offset".
161  */
162 ENTRY(getbootspec)
163         push    %ebp
164         mov     %esp, %ebp
165
166         push    %esi
167         push    %ebx
168
169         movw    0x8(%ebp), %si
170         mov     $0x7f, %edx
171
172         /* prot_to_real will set %es to BOOTSEG */
173         call    EXT(prot_to_real)       /* enter real mode */
174         movw    $0x4b01, %ax            /* (do not) terminate disk emulation */
175         movb    $0x7f, %dl              /* any drive */
176
177         sti
178         int     $0x13
179         cli
180
181         /* save return value (actually movw %ax, %bx) */
182         mov     %eax, %ebx
183
184         data32
185         call    EXT(real_to_prot)       /* back to protected mode */
186
187         xor     %eax, %eax
188         movb    %bh, %al                /* return value in %ax */
189
190         pop     %ebx
191         pop     %esi
192         pop     %ebp
193
194         ret
195
196
197 /*
198  * int
199  * biosreadlba(struct daddrpacket *daddr)
200  *      Read sectors using the BIOS "read extended" function
201  * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
202  *      Call with       %ah = 0x42
203  *                      %dl = drive (0x0 for floppy disk, or emulated CD)
204  *                      %ds:%si = ptr to disk address packet
205  *      Return:
206  *                      %ah = 0x0 on success; err code on failure
207  */
208
209 ENTRY(biosreadlba)
210         push    %ebp
211         mov     %esp, %ebp
212
213         push    %ebx
214         push    %esi
215
216         movw    8(%ebp), %si
217         movl    $0, %edx                /* emulated CD is always drive 0 */
218
219         /* prot_to_real will set %es to BOOTSEG */
220         call    EXT(prot_to_real)       /* enter real mode */
221         movw    $0x4200, %ax            /* subfunction */
222         movb    $0, %dl
223
224         sti
225         int     $0x13
226         cli
227
228         /* save return value (actually movw %ax, %bx) */
229         mov     %eax, %ebx
230
231         data32
232         call    EXT(real_to_prot)       /* back to protected mode */
233
234         xor     %eax, %eax
235         movb    %bh, %al                /* return value in %ax */
236
237         pop     %esi
238         pop     %ebx
239         pop     %ebp
240
241         ret
242
243 #endif /* !CDBOOT */
244
245 /*
246  * putc(ch)
247  * BIOS call "INT 10H Function 0Eh" to write character to console
248  *      Call with       %ah = 0x0e
249  *                      %al = character
250  *                      %bh = page
251  *                      %bl = foreground color ( graphics modes)
252  */
253
254
255 ENTRY(putc)
256         push    %ebp
257         mov     %esp, %ebp
258         push    %ebx
259         push    %esi
260         push    %edi
261
262         movb    0x8(%ebp), %cl
263
264         call    EXT(prot_to_real)
265
266         data32
267         mov     $0x1, %ebx              /* %bh=0, %bl=1 (blue) */
268         movb    $0xe, %ah
269         movb    %cl, %al
270         sti
271         int     $0x10                   /* display a byte */
272         cli
273
274         data32
275         call    EXT(real_to_prot)
276
277         pop     %edi
278         pop     %esi
279         pop     %ebx
280         pop     %ebp
281         ret
282
283
284 /*
285  * getc()
286  * BIOS call "INT 16H Function 00H" to read character from keyboard
287  *      Call with       %ah = 0x0
288  *      Return:         %ah = keyboard scan code
289  *                      %al = ASCII character
290  */
291
292 ENTRY(getc)
293         push    %ebp
294         mov     %esp, %ebp
295         push    %ebx                    /* save %ebx */
296         push    %esi
297         push    %edi
298
299         call    EXT(prot_to_real)
300
301         movb    $0x0, %ah
302         sti
303         int     $0x16
304         cli
305
306         movb    %al, %bl                /* real_to_prot uses %eax */
307
308         data32
309         call    EXT(real_to_prot)
310
311         xor     %eax, %eax
312         movb    %bl, %al
313
314         pop     %edi
315         pop     %esi
316         pop     %ebx
317         pop     %ebp
318         ret
319 /*
320  * ischar()
321  *      if there is a character pending, return it; otherwise return 0
322  * BIOS call "INT 16H Function 01H" to check whether a character is pending
323  *      Call with       %ah = 0x1
324  *      Return:
325  *              If key waiting to be input:
326  *                      %ah = keyboard scan code
327  *                      %al = ASCII character
328  *                      Zero flag = clear
329  *              else
330  *                      Zero flag = set
331  */
332 ENTRY(ischar)
333         push    %ebp
334         mov     %esp, %ebp
335         push    %ebx
336         push    %esi
337         push    %edi
338
339         call    EXT(prot_to_real)       /* enter real mode */
340
341         xor     %ebx, %ebx
342         movb    $0x1, %ah
343         sti
344         int     $0x16
345         cli
346         data32
347         jz      nochar
348         movb    %al, %bl
349
350 nochar:
351         data32
352         call    EXT(real_to_prot)
353
354         xor     %eax, %eax
355         movb    %bl, %al
356
357         pop     %edi
358         pop     %esi
359         pop     %ebx
360         pop     %ebp
361         ret
362
363 /*
364  *
365  * get_diskinfo():  return a word that represents the
366  *      max number of sectors and heads and drives for this device
367  *
368  */
369
370 ENTRY(get_diskinfo)
371         push    %ebp
372         mov     %esp, %ebp
373         push    %ebx
374         push    %esi
375         push    %edi
376
377         movb    0x8(%ebp), %dl          /* diskinfo(drive #) */
378         call    EXT(prot_to_real)       /* enter real mode */
379
380         movb    $0x8, %ah               /* ask for disk info */
381
382         sti
383         int     $0x13
384         cli
385
386         jnc     ok
387         /*
388          * Urk.  Call failed.  It is not supported for floppies by old BIOS's.
389          * Guess it's a 15-sector floppy.
390          */
391         subb    %ah, %ah                /* %ax = 0 */
392         movb    %al, %al
393         movb    %ah, %bh                /* %bh = 0 */
394         movb    $2, %bl                 /* %bl  bits 0-3 = drive type,
395                                                 bit    2 = 1.2M */
396         movb    $79, %ch                /* max track */
397         movb    $15, %cl                /* max sector */
398         movb    $1, %dh                 /* max head */
399         movb    $1, %dl                 /* # floppy drives installed */
400         /* es:di = parameter table */
401         /* carry = 0 */
402 ok:
403
404         data32
405         call    EXT(real_to_prot)       /* back to protected mode */
406
407         /* 
408          * form a longword representing all this gunk:
409          *       6 bit zero
410          *      10 bit max cylinder (0 based)
411          *       8 bit max head (0 based)
412          *       2 bit zero
413          *       6 bit max sector (1 based) = # sectors
414          */
415         movb    %cl, %al                /* Upper two bits of cylinder count */
416         andl    $192,%eax       
417         leal    0(,%eax,4),%eax         /* << 2 */
418         movb    %ch, %al                /* Lower 8 bits */
419         sall    $16,%eax                /* << 16 */
420         movb    %dh, %ah                /* max head */
421         andb    $0x3f, %cl              /* mask of cylinder gunk */
422         movb    %cl, %al                /* max sector (and # sectors) */
423
424         pop     %edi
425         pop     %esi
426         pop     %ebx
427         pop     %ebp
428         ret
429
430 /*
431  *
432  * memsize(i) :  return the memory size in KB. i == 0 for conventional memory,
433  *              i == 1 for extended memory
434  *      BIOS call "INT 12H" to get conventional memory size
435  *      BIOS call "INT 15H, AH=88H" to get extended memory size
436  *              Both have the return value in AX.
437  *
438  */
439
440 ENTRY(memsize)
441         push    %ebp
442         mov     %esp, %ebp
443         push    %ebx
444         push    %esi
445         push    %edi
446
447         mov     8(%ebp), %ebx
448
449         call    EXT(prot_to_real)       /* enter real mode */
450
451         cmpb    $0x1, %bl
452         data32
453         je      xext
454         
455         sti
456         int     $0x12
457         cli
458         data32
459         jmp     xdone
460
461 xext:   movb    $0x88, %ah
462         sti
463         int     $0x15
464         cli
465
466 xdone:
467         pushl   $0                      /* actually pushw $0 */
468         pushl   %eax                    /* actually pushw %ax */
469
470         data32
471         call    EXT(real_to_prot)
472
473         pop     %eax
474         pop     %edi
475         pop     %esi
476         pop     %ebx
477         pop     %ebp
478         ret