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