]> git.sur5r.net Git - u-boot/blob - arch/x86/lib/bios.S
serial: Remove CONFIG_SERIAL_MULTI from remaining sources
[u-boot] / arch / x86 / 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          * All interrupt jumptable entries jump to here after pushing the
251          * interrupt vector number onto the stack.
252          */
253 any_interrupt16:
254         MAKE_BIOS_STACK
255
256 gs      movw    OFFS_VECTOR(%bp), %ax
257         cmpw    $0x10, %ax
258         je      Lint_10h
259         cmpw    $0x11, %ax
260         je      Lint_11h
261         cmpw    $0x12, %ax
262         je      Lint_12h
263         cmpw    $0x13, %ax
264         je      Lint_13h
265         cmpw    $0x15, %ax
266         je      Lint_15h
267         cmpw    $0x16, %ax
268         je      Lint_16h
269         cmpw    $0x1a, %ax
270         je      Lint_1ah
271         movw    $0xffff, %ax
272         jmp     Lout
273 Lint_10h:
274         /* VGA BIOS services */
275         call    bios_10h
276         jmp     Lout
277 Lint_11h:
278         call    bios_11h
279         jmp     Lout
280 Lint_12h:
281         call    bios_12h
282         jmp     Lout
283 Lint_13h:
284         /* BIOS disk services */
285         call    bios_13h
286         jmp     Lout
287 Lint_15h:
288         /* Misc. BIOS services */
289         call    bios_15h
290         jmp     Lout
291 Lint_16h:
292         /* keyboard services */
293         call    bios_16h
294         jmp     Lout
295 Lint_1ah:
296         /* PCI bios */
297         call    bios_1ah
298         jmp     Lout
299 Lout:
300         cmpw    $0, %ax
301         je      Lhandeled
302
303         /*
304          * Insert code for unhandeled INTs here.
305          *
306          * ROLO prints a message to the console we could do that but then
307          * we're in 16bit mode so we'll have to get back into 32bit mode
308          * to use the console I/O routines (if we do this we should make
309          * int 0x10 and int 0x16 work as well)
310          */
311 Lhandeled:
312         RESTORE_CALLERS_STACK
313
314         /* dump vector number */
315         addw    $2,%sp
316
317         /* return from interrupt */
318         iret
319
320 /*
321  ************************************************************
322  * BIOS interrupt 10h -- VGA services
323  ************************************************************
324  */
325 bios_10h:
326 gs      movw    OFFS_AX(%bp), %ax
327         shrw    $8, %ax
328         cmpw    $0x3, %ax
329         je      Lcur_pos
330         cmpw    $0xf, %ax
331         je      Lvid_state
332         cmpw    $0x12, %ax
333         je      Lvid_cfg
334         movw    $0xffff, %ax
335         ret
336 Lcur_pos:
337         /* Read Cursor Position and Size */
338 gs      movw    $0, OFFS_CX(%bp)
339 gs      movw    $0, OFFS_DX(%bp)
340         xorw    %ax, %ax
341         ret
342 Lvid_state:
343         /* Get Video State - 80 columns, 80x25, 16 colors */
344 gs      movw    $(80 << 8|0x03), OFFS_AX(%bp)
345 gs      movw    $0, OFFS_BX(%bp)
346         xorw    %ax, %ax
347         ret
348 Lvid_cfg:
349         /* Video Subsystem Configuration (EGA/VGA) - indicate CGA/MDA/HGA */
350 gs      movw    $0x10, OFFS_BX(%bp)
351         xorw    %ax, %ax
352         ret
353
354 /*
355  ************************************************************
356  * BIOS interrupt 11h -- Equipment determination
357  ************************************************************
358  */
359
360 bios_11h:
361 cs      movw    bios_equipment, %ax
362 gs      movw    %ax, OFFS_AX(%bp)
363         xorw    %ax, %ax
364         ret
365
366 /*
367  ************************************************************
368  * BIOS interrupt 12h -- Get Memory Size
369  ************************************************************
370  */
371 bios_12h:
372 cs      movw    ram_in_64kb_chunks, %ax
373         cmpw    $0xa, %ax
374         ja      b12_more_than_640k
375         shlw    $6, %ax
376         jmp     b12_return
377 b12_more_than_640k:
378         movw    $0x280, %ax
379 b12_return:
380         /* return number of kilobytes in ax */
381 gs      movw    %ax, OFFS_AX(%bp)
382
383 gs      movw    OFFS_FLAGS(%bp), %ax
384
385         /* clear carry -- function succeeded */
386         andw    $0xfffe, %ax
387 gs      movw    %ax, OFFS_FLAGS(%bp)
388
389         xorw    %ax, %ax
390         ret
391
392 /*
393  ************************************************************
394  * BIOS interrupt 13h -- Disk services
395  ************************************************************
396  */
397 bios_13h:
398 gs      movw    OFFS_AX(%bp), %ax
399         shrw    $8, %ax
400         cmpw    $0x15, %ax
401         je      Lfunc_15h
402         movw    $0xffff, %ax
403         ret
404 Lfunc_15h:
405 gs      movw    OFFS_AX(%bp), %ax
406
407         /* return AH=0->drive not present */
408         andw    $0x00ff, %ax
409 gs      movw    %ax, OFFS_AX(%bp)
410         xorw    %ax, %ax
411         ret
412
413 /*
414  ***********************************************************
415  * BIOS interrupt 15h -- Miscellaneous services
416  ***********************************************************
417  */
418 bios_15h:
419 gs      movw    OFFS_AX(%bp), %ax
420         shrw    $8, %ax
421         cmpw    $0xc0, %ax
422         je      Lfunc_c0h
423         cmpw    $0xe8, %ax
424         je      Lfunc_e8h
425         cmpw    $0x88, %ax
426         je      Lfunc_88h
427         movw    $0xffff, %ax
428         ret
429
430 Lfunc_c0h:
431         /* Return System Configuration Parameters (PS2 only) */
432 gs      movw    OFFS_FLAGS(%bp), %ax
433
434         /* return carry -- function not supported */
435         orw     $1, %ax
436 gs      movw    %ax, OFFS_FLAGS(%bp)
437         xorw    %ax, %ax
438         ret
439
440 Lfunc_e8h:
441 gs      movw    OFFS_AX(%bp), %ax
442         andw    $0xff, %ax
443         cmpw    $1, %ax
444         je      Lfunc_e801h
445 gs      movw    OFFS_FLAGS(%bp), %ax
446
447         /* return carry -- function not supported */
448         orw     $1, %ax
449 gs      movw    %ax, OFFS_FLAGS(%bp)
450         xorw    %ax, %ax
451         ret
452
453 Lfunc_e801h:
454         /* Get memory size for >64M Configurations */
455 cs      movw    ram_in_64kb_chunks, %ax
456         cmpw    $0x100, %ax
457         ja      e801_more_than_16mb
458
459         /* multiply by 64 */
460         shlw    $6, %ax
461
462         /* 1st meg does not count */
463         subw    $0x400, %ax
464
465         /* return memory size between 1M and 16M in 1kb chunks in AX and CX */
466 gs      movw    %ax, OFFS_AX(%bp)
467 gs      movw    %ax, OFFS_CX(%bp)
468
469         /* set BX and DX to 0*/
470 gs      movw    $0, OFFS_BX(%bp)
471 gs      movw    $0, OFFS_DX(%bp)
472 gs      movw    OFFS_FLAGS(%bp), %ax
473
474         /* clear carry -- function succeeded */
475         andw    $0xfffe, %ax
476 gs      movw    %ax, OFFS_FLAGS(%bp)
477         xorw    %ax, %ax
478         ret
479
480 e801_more_than_16mb:
481         /* subtract 16MB */
482         subw    $0x100, %ax
483
484         /* return 0x3c00 (16MB-1MB) in AX and CX */
485 gs      movw    $0x3c00, OFFS_AX(%bp)
486 gs      movw    $0x3c00, OFFS_CX(%bp)
487
488         /* set BX and DX to number of 64kb chunks above 16MB */
489 gs      movw    %ax, OFFS_BX(%bp)
490 gs      movw    %ax, OFFS_DX(%bp)
491
492 gs      movw    OFFS_FLAGS(%bp), %ax
493
494         /* clear carry -- function succeeded */
495         andw    $0xfffe, %ax
496 gs      movw    %ax, OFFS_FLAGS(%bp)
497         xorw    %ax, %ax
498         ret
499
500 Lfunc_88h:
501 cs      movw    ram_in_64kb_chunks, %ax
502         cmpw    $0x100, %ax
503         jna     b88_not_more_than16
504         movw    $0x100, %ax
505 b88_not_more_than16:
506         shlw    $6, %ax
507
508         /* 1st meg does not count */
509         subw    $0x400, %ax
510
511         /* return number of kilobytes between 16MB and 16MB in ax */
512 gs      movw    %ax, OFFS_AX(%bp)
513
514 gs      movw    OFFS_FLAGS(%bp), %ax
515
516         /* clear carry -- function succeeded */
517         andw    $0xfffe, %ax
518 gs      movw    %ax, OFFS_FLAGS(%bp)
519
520         xorw    %ax, %ax
521         ret
522
523 /*
524  ************************************************************
525  * BIOS interrupt 16h -- keyboard services
526  ************************************************************
527  */
528 bios_16h:
529 gs      movw    OFFS_AX(%bp), %ax
530         shrw    $8, %ax
531         cmpw    $0x03, %ax
532         je      Lfunc_03h
533         movw    $0xffff, %ax
534         ret
535 Lfunc_03h:
536         /* do nothing -- function not supported */
537         xorw    %ax, %ax
538         ret
539
540 /*
541  ************************************************************
542  * BIOS interrupt 1ah -- PCI bios
543  ************************************************************
544  */
545 bios_1ah:
546 gs      movw    OFFS_AX(%bp), %ax
547         cmpb    $0xb1, %ah
548         je      Lfunc_b1h
549         movw    $0xffff, %ax
550         ret
551 Lfunc_b1h:
552         call    realmode_pci_bios
553
554         /* do nothing -- function not supported */
555         xorw    %ax, %ax
556         ret
557
558
559 .globl ram_in_64kb_chunks
560 .hidden ram_in_64kb_chunks
561 .type ram_in_64kb_chunks, @function
562 ram_in_64kb_chunks:
563         .word   0
564
565 .globl bios_equipment
566 .hidden bios_equipment
567 .type bios_equipment, @function
568 bios_equipment:
569         .word   0