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