blob: 4606419c1b0e25c042683375b6cc13a5ad7a1752 [file] [log] [blame]
wdenk591dda52002-11-18 00:14:45 +00001/*
2 * (C) Copyright 2002
3 * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
wdenk57b2d802003-06-27 21:31:46 +00004 *
wdenk591dda52002-11-18 00:14:45 +00005 * 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
wdenkabda5ca2003-05-31 18:35:21 +000033#include "bios.h"
34
wdenk591dda52002-11-18 00:14:45 +000035/*
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
wdenk591dda52002-11-18 00:14:45 +000045
46.section .bios, "ax"
47.code16
48.org 0
wdenk57b2d802003-06-27 21:31:46 +000049 /* a call to f000:0 should warmboot */
wdenkabda5ca2003-05-31 18:35:21 +000050 jmp realmode_reset
wdenk57b2d802003-06-27 21:31:46 +000051
wdenk591dda52002-11-18 00:14:45 +000052.globl rm_int00
53rm_int00:
54 pushw $0
55 jmp any_interrupt16
56.globl rm_int01
57rm_int01:
58 pushw $1
59 jmp any_interrupt16
60.globl rm_int02
61rm_int02:
62 pushw $2
63 jmp any_interrupt16
64.globl rm_int03
65rm_int03:
66 pushw $3
67 jmp any_interrupt16
68.globl rm_int04
69rm_int04:
70 pushw $4
71 jmp any_interrupt16
72.globl rm_int05
73rm_int05:
74 pushw $5
75 jmp any_interrupt16
76.globl rm_int06
77rm_int06:
78 pushw $6
79 jmp any_interrupt16
80.globl rm_int07
81rm_int07:
82 pushw $7
83 jmp any_interrupt16
84.globl rm_int08
85rm_int08:
86 pushw $8
87 jmp any_interrupt16
88.globl rm_int09
89rm_int09:
90 pushw $9
91 jmp any_interrupt16
92.globl rm_int0a
93rm_int0a:
94 pushw $10
95 jmp any_interrupt16
96.globl rm_int0b
97rm_int0b:
98 pushw $11
99 jmp any_interrupt16
100.globl rm_int0c
101rm_int0c:
102 pushw $12
103 jmp any_interrupt16
104.globl rm_int0d
105rm_int0d:
106 pushw $13
107 jmp any_interrupt16
108.globl rm_int0e
109rm_int0e:
110 pushw $14
111 jmp any_interrupt16
112.globl rm_int0f
113rm_int0f:
114 pushw $15
115 jmp any_interrupt16
116.globl rm_int10
117rm_int10:
118 pushw $16
119 jmp any_interrupt16
120.globl rm_int11
121rm_int11:
122 pushw $17
123 jmp any_interrupt16
124.globl rm_int12
125rm_int12:
126 pushw $18
127 jmp any_interrupt16
128.globl rm_int13
129rm_int13:
130 pushw $19
131 jmp any_interrupt16
132.globl rm_int14
133rm_int14:
134 pushw $20
135 jmp any_interrupt16
136.globl rm_int15
137rm_int15:
138 pushw $21
139 jmp any_interrupt16
140.globl rm_int16
141rm_int16:
142 pushw $22
143 jmp any_interrupt16
144.globl rm_int17
145rm_int17:
146 pushw $23
147 jmp any_interrupt16
148.globl rm_int18
149rm_int18:
150 pushw $24
151 jmp any_interrupt16
152.globl rm_int19
153rm_int19:
154 pushw $25
155 jmp any_interrupt16
156.globl rm_int1a
157rm_int1a:
158 pushw $26
159 jmp any_interrupt16
160.globl rm_int1b
161rm_int1b:
162 pushw $27
163 jmp any_interrupt16
164.globl rm_int1c
165rm_int1c:
166 pushw $28
167 jmp any_interrupt16
168.globl rm_int1d
169rm_int1d:
170 pushw $29
171 jmp any_interrupt16
172.globl rm_int1e
173rm_int1e:
174 pushw $30
175 jmp any_interrupt16
176.globl rm_int1f
177rm_int1f:
178 pushw $31
179 jmp any_interrupt16
180.globl rm_def_int
181rm_def_int:
182 iret
183
wdenk57b2d802003-06-27 21:31:46 +0000184
wdenk591dda52002-11-18 00:14:45 +0000185 /*
186 * All interrupt jumptable entries jump to here
187 * after pushing the interrupt vector number onto the
188 * stack.
189 */
190any_interrupt16:
wdenk57b2d802003-06-27 21:31:46 +0000191 MAKE_BIOS_STACK
wdenk591dda52002-11-18 00:14:45 +0000192
193gs movw OFFS_VECTOR(%bp), %ax
194 cmpw $0x10, %ax
wdenk57b2d802003-06-27 21:31:46 +0000195 je Lint_10h
wdenk591dda52002-11-18 00:14:45 +0000196 cmpw $0x11, %ax
197 je Lint_11h
wdenkabda5ca2003-05-31 18:35:21 +0000198 cmpw $0x12, %ax
199 je Lint_12h
wdenk591dda52002-11-18 00:14:45 +0000200 cmpw $0x13, %ax
201 je Lint_13h
202 cmpw $0x15, %ax
203 je Lint_15h
204 cmpw $0x16, %ax
205 je Lint_16h
wdenkabda5ca2003-05-31 18:35:21 +0000206 cmpw $0x1a, %ax
207 je Lint_1ah
wdenk591dda52002-11-18 00:14:45 +0000208 movw $0xffff, %ax
209 jmp Lout
210Lint_10h: /* VGA BIOS services */
211 call bios_10h
212 jmp Lout
wdenk57b2d802003-06-27 21:31:46 +0000213Lint_11h:
wdenk591dda52002-11-18 00:14:45 +0000214 call bios_11h
215 jmp Lout
wdenk57b2d802003-06-27 21:31:46 +0000216Lint_12h:
wdenkabda5ca2003-05-31 18:35:21 +0000217 call bios_12h
218 jmp Lout
wdenk591dda52002-11-18 00:14:45 +0000219Lint_13h: /* BIOS disk services */
220 call bios_13h
221 jmp Lout
222Lint_15h: /* Misc. BIOS services */
223 call bios_15h
224 jmp Lout
225Lint_16h: /* keyboard services */
226 call bios_16h
227 jmp Lout
wdenkabda5ca2003-05-31 18:35:21 +0000228Lint_1ah: /* PCI bios */
229 call bios_1ah
230 jmp Lout
wdenk57b2d802003-06-27 21:31:46 +0000231Lout:
wdenk591dda52002-11-18 00:14:45 +0000232 cmpw $0, %ax
233 je Lhandeled
wdenk57b2d802003-06-27 21:31:46 +0000234
wdenk591dda52002-11-18 00:14:45 +0000235 /* Insert code for unhandeled INTs here.
236 *
wdenk57b2d802003-06-27 21:31:46 +0000237 * ROLO prints a message to the console
wdenk591dda52002-11-18 00:14:45 +0000238 * (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 */
243Lhandeled:
wdenkabda5ca2003-05-31 18:35:21 +0000244 RESTORE_CALLERS_STACK
wdenk591dda52002-11-18 00:14:45 +0000245 addw $2,%sp /* dump vector number */
246 iret /* return from interrupt */
247
248
249/*
250 ************************************************************
251 * BIOS interrupt 10h -- VGA services
252 ************************************************************
253 */
254bios_10h:
255gs 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
265Lcur_pos: /* Read Cursor Position and Size */
266gs movw $0, OFFS_CX(%bp)
267gs movw $0, OFFS_DX(%bp)
268 xorw %ax, %ax
269 ret
270Lvid_state: /* Get Video State */
271gs movw $(80 << 8|0x03), OFFS_AX(%bp) /* 80 columns, 80x25, 16 colors */
272gs movw $0, OFFS_BX(%bp)
273 xorw %ax, %ax
274 ret
275Lvid_cfg: /* Video Subsystem Configuration (EGA/VGA) */
276gs 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
287bios_11h:
wdenkabda5ca2003-05-31 18:35:21 +0000288cs movw bios_equipment, %ax
wdenk57b2d802003-06-27 21:31:46 +0000289gs movw %ax, OFFS_AX(%bp)
wdenk591dda52002-11-18 00:14:45 +0000290 xorw %ax, %ax
291 ret
292
293
294/*
295 ************************************************************
wdenkabda5ca2003-05-31 18:35:21 +0000296 * BIOS interrupt 12h -- Get Memory Size
297 ************************************************************
298 */
299bios_12h:
300cs movw ram_in_64kb_chunks, %ax
301 cmpw $0xa, %ax
302 ja b12_more_than_640k
303 shlw $6, %ax
304 jmp b12_return
305b12_more_than_640k:
306 movw $0x280, %ax
307b12_return:
308gs movw %ax, OFFS_AX(%bp) /* return number of kilobytes in ax */
309
310gs movw OFFS_FLAGS(%bp), %ax
311 andw $0xfffe, %ax /* clear carry -- function succeeded */
312gs movw %ax, OFFS_FLAGS(%bp)
313
314 xorw %ax, %ax
315 ret
316
317
318/*
319 ************************************************************
wdenk591dda52002-11-18 00:14:45 +0000320 * BIOS interrupt 13h -- Disk services
321 ************************************************************
322 */
323bios_13h:
324gs movw OFFS_AX(%bp), %ax
325 shrw $8, %ax
326 cmpw $0x15, %ax
327 je Lfunc_15h
328 movw $0xffff, %ax
329 ret
wdenk57b2d802003-06-27 21:31:46 +0000330Lfunc_15h:
wdenk591dda52002-11-18 00:14:45 +0000331gs movw OFFS_AX(%bp), %ax
332 andw $0xff, %ax /* return AH=0->drive not present */
333gs movw %ax, OFFS_AX(%bp)
334 xorw %ax, %ax
335 ret
wdenk57b2d802003-06-27 21:31:46 +0000336
wdenk591dda52002-11-18 00:14:45 +0000337
338/*
339 ***********************************************************
340 * BIOS interrupt 15h -- Miscellaneous services
341 ***********************************************************
342 */
343bios_15h:
344gs 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
355Lfunc_c0h: /* Return System Configuration Parameters (PS2 only) */
356gs movw OFFS_FLAGS(%bp), %ax
357 orw $1, %ax /* return carry -- function not supported */
358gs movw %ax, OFFS_FLAGS(%bp)
359 xorw %ax, %ax
360 ret
wdenk57b2d802003-06-27 21:31:46 +0000361
wdenk591dda52002-11-18 00:14:45 +0000362Lfunc_e8h:
363gs movw OFFS_AX(%bp), %ax
364 andw $0xff, %ax
365 cmpw $1, %ax
366 je Lfunc_e801h
367gs movw OFFS_FLAGS(%bp), %ax
368 orw $1, %ax /* return carry -- function not supported */
369gs movw %ax, OFFS_FLAGS(%bp)
370 xorw %ax, %ax
371 ret
wdenk57b2d802003-06-27 21:31:46 +0000372
wdenk591dda52002-11-18 00:14:45 +0000373Lfunc_e801h: /* Get memory size for >64M Configurations */
wdenkabda5ca2003-05-31 18:35:21 +0000374cs 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 */
wdenk57b2d802003-06-27 21:31:46 +0000379
wdenkabda5ca2003-05-31 18:35:21 +0000380gs movw %ax, OFFS_AX(%bp) /* return memory size between 1M and 16M in 1kb chunks in AX and CX */
wdenk591dda52002-11-18 00:14:45 +0000381gs movw %ax, OFFS_CX(%bp)
wdenkabda5ca2003-05-31 18:35:21 +0000382gs movw $0, OFFS_BX(%bp) /* set BX and DX to 0*/
wdenk57b2d802003-06-27 21:31:46 +0000383gs movw $0, OFFS_DX(%bp)
wdenk591dda52002-11-18 00:14:45 +0000384gs movw OFFS_FLAGS(%bp), %ax
385 andw $0xfffe, %ax /* clear carry -- function succeeded */
386gs movw %ax, OFFS_FLAGS(%bp)
387 xorw %ax, %ax
388 ret
wdenk57b2d802003-06-27 21:31:46 +0000389
wdenkabda5ca2003-05-31 18:35:21 +0000390e801_more_than_16mb:
wdenk57b2d802003-06-27 21:31:46 +0000391 subw $0x100, %ax /* subtract 16MB */
392
wdenkabda5ca2003-05-31 18:35:21 +0000393gs movw $0x3c00, OFFS_AX(%bp) /* return 0x3c00 (16MB-1MB) in AX and CX */
wdenk591dda52002-11-18 00:14:45 +0000394gs movw $0x3c00, OFFS_CX(%bp)
wdenkabda5ca2003-05-31 18:35:21 +0000395gs movw %ax, OFFS_BX(%bp) /* set BX and DX to number of 64kb chunks above 16MB */
wdenk57b2d802003-06-27 21:31:46 +0000396gs movw %ax, OFFS_DX(%bp)
wdenk591dda52002-11-18 00:14:45 +0000397
398gs movw OFFS_FLAGS(%bp), %ax
399 andw $0xfffe, %ax /* clear carry -- function succeeded */
400gs movw %ax, OFFS_FLAGS(%bp)
401 xorw %ax, %ax
402 ret
403
404Lfunc_88h:
wdenkabda5ca2003-05-31 18:35:21 +0000405cs movw ram_in_64kb_chunks, %ax
406 cmpw $0x100, %ax
407 jna b88_not_more_than16
408 movw $0x100, %ax
409b88_not_more_than16:
wdenk591dda52002-11-18 00:14:45 +0000410 shlw $6, %ax
wdenkabda5ca2003-05-31 18:35:21 +0000411 subw $0x400, %ax /* 1st meg does not count */
wdenk57b2d802003-06-27 21:31:46 +0000412
wdenkabda5ca2003-05-31 18:35:21 +0000413gs movw %ax, OFFS_AX(%bp) /* return number of kilobytes between 16MB and 16MB in ax */
wdenk591dda52002-11-18 00:14:45 +0000414
415gs movw OFFS_FLAGS(%bp), %ax
416 andw $0xfffe, %ax /* clear carry -- function succeeded */
417gs movw %ax, OFFS_FLAGS(%bp)
418
419 xorw %ax, %ax
420 ret
421
422
423/*
424 ************************************************************
425 * BIOS interrupt 16h -- keyboard services
426 ************************************************************
427 */
428bios_16h:
429gs movw OFFS_AX(%bp), %ax
430 shrw $8, %ax
431 cmpw $0x03, %ax
432 je Lfunc_03h
433 movw $0xffff, %ax
434 ret
435Lfunc_03h:
436 xorw %ax, %ax /* do nothing -- function not supported */
437 ret
438
wdenkabda5ca2003-05-31 18:35:21 +0000439/*
440 ************************************************************
441 * BIOS interrupt 1ah -- PCI bios
442 ************************************************************
443 */
444bios_1ah:
445gs movw OFFS_AX(%bp), %ax
446 cmpb $0xb1, %ah
447 je Lfunc_b1h
448 movw $0xffff, %ax
449 ret
450Lfunc_b1h:
451 call realmode_pci_bios
452 xorw %ax, %ax /* do nothing -- function not supported */
453 ret
454
wdenk591dda52002-11-18 00:14:45 +0000455
456.globl ram_in_64kb_chunks
457ram_in_64kb_chunks:
458 .word 0
459
460.globl bios_equipment
461bios_equipment:
462 .word 0