]> git.sur5r.net Git - u-boot/blob - arch/i386/lib/bios.S
Merge branch 'at91' of git://git.denx.de/u-boot-atmel
[u-boot] / arch / i386 / lib / bios.S
1 /*
2  * (C) Copyright 2002
3  * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * Based on msbios.c from rolo 1.6:
26  *----------------------------------------------------------------------
27  * (C) Copyright 2000
28  * Sysgo Real-Time Solutions GmbH
29  * Klein-Winternheim, Germany
30  *----------------------------------------------------------------------
31  */
32
33 #include "bios.h"
34
35 /*
36  * During it's initialization phase, before switching to protected
37  * mode, the Linux Kernel makes a few BIOS calls. This won't work
38  * if the board does not have a BIOS.
39  *
40  * This is a very minimalisic BIOS that supplies just enough
41  * functionality to keep the Linux Kernel happy. It is NOT
42  * a general purpose replacement for a real BIOS !!
43  */
44
45
46 .section .bios, "ax"
47 .code16
48 .org 0
49         /* a call to f000:0 should warmboot */
50         jmp     realmode_reset
51
52 .globl rm_int00
53 .hidden rm_int00
54 .type rm_int00, @function
55 rm_int00:
56         pushw   $0
57         jmp     any_interrupt16
58 .globl rm_int01
59 .hidden rm_int01
60 .type rm_int01, @function
61 rm_int01:
62         pushw   $1
63         jmp     any_interrupt16
64 .globl rm_int02
65 .hidden rm_int02
66 .type rm_int02, @function
67 rm_int02:
68         pushw   $2
69         jmp     any_interrupt16
70 .globl rm_int03
71 .hidden rm_int03
72 .type rm_int03, @function
73 rm_int03:
74         pushw   $3
75         jmp     any_interrupt16
76 .globl rm_int04
77 .hidden rm_int04
78 .type rm_int04, @function
79 rm_int04:
80         pushw   $4
81         jmp     any_interrupt16
82 .globl rm_int05
83 .hidden rm_int05
84 .type rm_int05, @function
85 rm_int05:
86         pushw   $5
87         jmp     any_interrupt16
88 .globl rm_int06
89 .hidden rm_int06
90 .type rm_int06, @function
91 rm_int06:
92         pushw   $6
93         jmp     any_interrupt16
94 .globl rm_int07
95 .hidden rm_int07
96 .type rm_int07, @function
97 rm_int07:
98         pushw   $7
99         jmp     any_interrupt16
100 .globl rm_int08
101 .hidden rm_int08
102 .type rm_int08, @function
103 rm_int08:
104         pushw   $8
105         jmp     any_interrupt16
106 .globl rm_int09
107 .hidden rm_int09
108 .type rm_int09, @function
109 rm_int09:
110         pushw   $9
111         jmp     any_interrupt16
112 .globl rm_int0a
113 .hidden rm_int0a
114 .type rm_int0a, @function
115 rm_int0a:
116         pushw   $10
117         jmp     any_interrupt16
118 .globl rm_int0b
119 .hidden rm_int0b
120 .type rm_int0b, @function
121 rm_int0b:
122         pushw   $11
123         jmp     any_interrupt16
124 .globl rm_int0c
125 .hidden rm_int0c
126 .type rm_int0c, @function
127 rm_int0c:
128         pushw   $12
129         jmp     any_interrupt16
130 .globl rm_int0d
131 .hidden rm_int0d
132 .type rm_int0d, @function
133 rm_int0d:
134         pushw   $13
135         jmp     any_interrupt16
136 .globl rm_int0e
137 .hidden rm_int0e
138 .type rm_int0e, @function
139 rm_int0e:
140         pushw   $14
141         jmp     any_interrupt16
142 .globl rm_int0f
143 .hidden rm_int0f
144 .type rm_int0f, @function
145 rm_int0f:
146         pushw   $15
147         jmp     any_interrupt16
148 .globl rm_int10
149 .hidden rm_int10
150 .type rm_int10, @function
151 rm_int10:
152         pushw   $16
153         jmp     any_interrupt16
154 .globl rm_int11
155 .hidden rm_int11
156 .type rm_int11, @function
157 rm_int11:
158         pushw   $17
159         jmp     any_interrupt16
160 .globl rm_int12
161 .hidden rm_int12
162 .type rm_int12, @function
163 rm_int12:
164         pushw   $18
165         jmp     any_interrupt16
166 .globl rm_int13
167 .hidden rm_int13
168 .type rm_int13, @function
169 rm_int13:
170         pushw   $19
171         jmp     any_interrupt16
172 .globl rm_int14
173 .hidden rm_int14
174 .type rm_int14, @function
175 rm_int14:
176         pushw   $20
177         jmp     any_interrupt16
178 .globl rm_int15
179 .hidden rm_int15
180 .type rm_int15, @function
181 rm_int15:
182         pushw   $21
183         jmp     any_interrupt16
184 .globl rm_int16
185 .hidden rm_int16
186 .type rm_int16, @function
187 rm_int16:
188         pushw   $22
189         jmp     any_interrupt16
190 .globl rm_int17
191 .hidden rm_int17
192 .type rm_int17, @function
193 rm_int17:
194         pushw   $23
195         jmp     any_interrupt16
196 .globl rm_int18
197 .hidden rm_int18
198 .type rm_int18, @function
199 rm_int18:
200         pushw   $24
201         jmp     any_interrupt16
202 .globl rm_int19
203 .hidden rm_int19
204 .type rm_int19, @function
205 rm_int19:
206         pushw   $25
207         jmp     any_interrupt16
208 .globl rm_int1a
209 .hidden rm_int1a
210 .type rm_int1a, @function
211 rm_int1a:
212         pushw   $26
213         jmp     any_interrupt16
214 .globl rm_int1b
215 .hidden rm_int1b
216 .type rm_int1b, @function
217 rm_int1b:
218         pushw   $27
219         jmp     any_interrupt16
220 .globl rm_int1c
221 .hidden rm_int1c
222 .type rm_int1c, @function
223 rm_int1c:
224         pushw   $28
225         jmp     any_interrupt16
226 .globl rm_int1d
227 .hidden rm_int1d
228 .type rm_int1d, @function
229 rm_int1d:
230         pushw   $29
231         jmp     any_interrupt16
232 .globl rm_int1e
233 .hidden rm_int1e
234 .type rm_int1e, @function
235 rm_int1e:
236         pushw   $30
237         jmp     any_interrupt16
238 .globl rm_int1f
239 .hidden rm_int1f
240 .type rm_int1f, @function
241 rm_int1f:
242         pushw   $31
243         jmp     any_interrupt16
244 .globl rm_def_int
245 .hidden rm_def_int
246 .type rm_def_int, @function
247 rm_def_int:
248         iret
249
250
251         /*
252          * All interrupt jumptable entries jump to here
253          * after pushing the interrupt vector number onto the
254          * stack.
255          */
256 any_interrupt16:
257         MAKE_BIOS_STACK
258
259 gs      movw    OFFS_VECTOR(%bp), %ax
260         cmpw    $0x10, %ax
261         je      Lint_10h
262         cmpw    $0x11, %ax
263         je      Lint_11h
264         cmpw    $0x12, %ax
265         je      Lint_12h
266         cmpw    $0x13, %ax
267         je      Lint_13h
268         cmpw    $0x15, %ax
269         je      Lint_15h
270         cmpw    $0x16, %ax
271         je      Lint_16h
272         cmpw    $0x1a, %ax
273         je      Lint_1ah
274         movw    $0xffff, %ax
275         jmp     Lout
276 Lint_10h:                                       /* VGA BIOS services */
277         call    bios_10h
278         jmp     Lout
279 Lint_11h:
280         call    bios_11h
281         jmp     Lout
282 Lint_12h:
283         call    bios_12h
284         jmp     Lout
285 Lint_13h:                                       /* BIOS disk services */
286         call    bios_13h
287         jmp     Lout
288 Lint_15h:                                       /* Misc. BIOS services */
289         call    bios_15h
290         jmp     Lout
291 Lint_16h:                                       /* keyboard services */
292         call    bios_16h
293         jmp     Lout
294 Lint_1ah:                                       /* PCI bios */
295         call    bios_1ah
296         jmp     Lout
297 Lout:
298         cmpw    $0, %ax
299         je      Lhandeled
300
301         /* Insert code for unhandeled INTs here.
302          *
303          * ROLO prints a message to the console
304          * (we could do that but then we're in 16bit mode
305          * so we'll have to get back into 32bit mode
306          * to use the console I/O routines (if we do this
307          * we shuls make int 0x10 and int 0x16 work as well))
308          */
309 Lhandeled:
310         RESTORE_CALLERS_STACK
311         addw    $2,%sp                          /* dump vector number */
312         iret                                    /* return from interrupt */
313
314
315 /*
316  ************************************************************
317  * BIOS interrupt 10h -- VGA services
318  ************************************************************
319  */
320 bios_10h:
321 gs      movw    OFFS_AX(%bp), %ax
322         shrw    $8, %ax
323         cmpw    $0x3, %ax
324         je      Lcur_pos
325         cmpw    $0xf, %ax
326         je      Lvid_state
327         cmpw    $0x12, %ax
328         je      Lvid_cfg
329         movw    $0xffff, %ax
330         ret
331 Lcur_pos:                                       /* Read Cursor Position and Size */
332 gs      movw    $0, OFFS_CX(%bp)
333 gs      movw    $0, OFFS_DX(%bp)
334         xorw    %ax, %ax
335         ret
336 Lvid_state:                                     /* Get Video State */
337 gs      movw    $(80 << 8|0x03), OFFS_AX(%bp)   /* 80 columns, 80x25, 16 colors */
338 gs      movw    $0, OFFS_BX(%bp)
339         xorw    %ax, %ax
340         ret
341 Lvid_cfg:       /* Video Subsystem Configuration (EGA/VGA) */
342 gs      movw    $0x10, OFFS_BX(%bp)             /* indicate CGA/MDA/HGA */
343         xorw    %ax, %ax
344         ret
345
346
347 /*
348  ************************************************************
349  * BIOS interrupt 11h -- Equipment determination
350  ************************************************************
351  */
352
353 bios_11h:
354 cs      movw    bios_equipment, %ax
355 gs      movw    %ax, OFFS_AX(%bp)
356         xorw    %ax, %ax
357         ret
358
359
360 /*
361  ************************************************************
362  * BIOS interrupt 12h -- Get Memory Size
363  ************************************************************
364  */
365 bios_12h:
366 cs      movw    ram_in_64kb_chunks, %ax
367         cmpw    $0xa, %ax
368         ja      b12_more_than_640k
369         shlw    $6, %ax
370         jmp     b12_return
371 b12_more_than_640k:
372         movw    $0x280, %ax
373 b12_return:
374 gs      movw    %ax, OFFS_AX(%bp)               /* return number of kilobytes in ax */
375
376 gs      movw    OFFS_FLAGS(%bp), %ax
377         andw    $0xfffe, %ax                    /* clear carry -- function succeeded */
378 gs      movw    %ax, OFFS_FLAGS(%bp)
379
380         xorw    %ax, %ax
381         ret
382
383
384 /*
385  ************************************************************
386  * BIOS interrupt 13h -- Disk services
387  ************************************************************
388  */
389 bios_13h:
390 gs      movw    OFFS_AX(%bp), %ax
391         shrw    $8, %ax
392         cmpw    $0x15, %ax
393         je      Lfunc_15h
394         movw    $0xffff, %ax
395         ret
396 Lfunc_15h:
397 gs      movw    OFFS_AX(%bp), %ax
398         andw    $0xff, %ax                      /* return AH=0->drive not present */
399 gs      movw    %ax, OFFS_AX(%bp)
400         xorw    %ax, %ax
401         ret
402
403
404 /*
405  ***********************************************************
406  * BIOS interrupt 15h -- Miscellaneous services
407  ***********************************************************
408  */
409 bios_15h:
410 gs      movw    OFFS_AX(%bp), %ax
411         shrw    $8, %ax
412         cmpw    $0xc0, %ax
413         je      Lfunc_c0h
414         cmpw    $0xe8, %ax
415         je      Lfunc_e8h
416         cmpw    $0x88, %ax
417         je      Lfunc_88h
418         movw    $0xffff, %ax
419         ret
420
421 Lfunc_c0h:                                      /* Return System Configuration Parameters (PS2 only) */
422 gs      movw    OFFS_FLAGS(%bp), %ax
423         orw     $1, %ax                         /* return carry -- function not supported */
424 gs      movw    %ax, OFFS_FLAGS(%bp)
425         xorw    %ax, %ax
426         ret
427
428 Lfunc_e8h:
429 gs      movw    OFFS_AX(%bp), %ax
430         andw    $0xff, %ax
431         cmpw    $1, %ax
432         je      Lfunc_e801h
433 gs      movw    OFFS_FLAGS(%bp), %ax
434         orw     $1, %ax                         /* return carry -- function not supported */
435 gs      movw    %ax, OFFS_FLAGS(%bp)
436         xorw    %ax, %ax
437         ret
438
439 Lfunc_e801h:                                    /* Get memory size for >64M Configurations */
440 cs      movw    ram_in_64kb_chunks, %ax
441         cmpw    $0x100, %ax
442         ja      e801_more_than_16mb
443         shlw    $6, %ax                         /* multiply by 64 */
444         subw    $0x400, %ax                     /* 1st meg does not count */
445
446 gs      movw    %ax, OFFS_AX(%bp)               /* return memory size between 1M and 16M in 1kb chunks in AX and CX */
447 gs      movw    %ax, OFFS_CX(%bp)
448 gs      movw    $0, OFFS_BX(%bp)                /* set BX and DX to 0*/
449 gs      movw    $0, OFFS_DX(%bp)
450 gs      movw    OFFS_FLAGS(%bp), %ax
451         andw    $0xfffe, %ax                    /* clear carry -- function succeeded */
452 gs      movw    %ax, OFFS_FLAGS(%bp)
453         xorw    %ax, %ax
454         ret
455
456 e801_more_than_16mb:
457         subw    $0x100, %ax                     /* subtract 16MB */
458
459 gs      movw    $0x3c00, OFFS_AX(%bp)           /* return 0x3c00 (16MB-1MB) in AX and CX */
460 gs      movw    $0x3c00, OFFS_CX(%bp)
461 gs      movw    %ax, OFFS_BX(%bp)               /* set BX and DX to number of 64kb chunks above 16MB */
462 gs      movw    %ax, OFFS_DX(%bp)
463
464 gs      movw    OFFS_FLAGS(%bp), %ax
465         andw    $0xfffe, %ax                    /* clear carry -- function succeeded */
466 gs      movw    %ax, OFFS_FLAGS(%bp)
467         xorw    %ax, %ax
468         ret
469
470 Lfunc_88h:
471 cs      movw    ram_in_64kb_chunks, %ax
472         cmpw    $0x100, %ax
473         jna     b88_not_more_than16
474         movw    $0x100, %ax
475 b88_not_more_than16:
476         shlw    $6, %ax
477         subw    $0x400, %ax                     /* 1st meg does not count */
478
479 gs      movw    %ax, OFFS_AX(%bp)               /* return number of kilobytes between 16MB and 16MB in ax */
480
481 gs      movw    OFFS_FLAGS(%bp), %ax
482         andw    $0xfffe, %ax                    /* clear carry -- function succeeded */
483 gs      movw    %ax, OFFS_FLAGS(%bp)
484
485         xorw    %ax, %ax
486         ret
487
488
489 /*
490  ************************************************************
491  * BIOS interrupt 16h -- keyboard services
492  ************************************************************
493  */
494 bios_16h:
495 gs      movw    OFFS_AX(%bp), %ax
496         shrw    $8, %ax
497         cmpw    $0x03, %ax
498         je      Lfunc_03h
499         movw    $0xffff, %ax
500         ret
501 Lfunc_03h:
502         xorw    %ax, %ax                        /* do nothing -- function not supported */
503         ret
504
505 /*
506  ************************************************************
507  * BIOS interrupt 1ah -- PCI bios
508  ************************************************************
509  */
510 bios_1ah:
511 gs      movw    OFFS_AX(%bp), %ax
512         cmpb    $0xb1, %ah
513         je      Lfunc_b1h
514         movw    $0xffff, %ax
515         ret
516 Lfunc_b1h:
517         call    realmode_pci_bios
518         xorw    %ax, %ax                        /* do nothing -- function not supported */
519         ret
520
521
522 .globl ram_in_64kb_chunks
523 .hidden ram_in_64kb_chunks
524 .type ram_in_64kb_chunks, @function
525 ram_in_64kb_chunks:
526         .word   0
527
528 .globl bios_equipment
529 .hidden bios_equipment
530 .type bios_equipment, @function
531 bios_equipment:
532         .word   0