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