|  | /* | 
|  | * (C) Copyright 2002 | 
|  | * Daniel Engström, Omicron Ceti AB, daniel@omicron.se | 
|  | * | 
|  | * See file CREDITS for list of people who contributed to this | 
|  | * project. | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU General Public License as | 
|  | * published by the Free Software Foundation; either version 2 of | 
|  | * the License, or (at your option) any later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License | 
|  | * along with this program; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 
|  | * MA 02111-1307 USA | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * Based on msbios.c from rolo 1.6: | 
|  | *---------------------------------------------------------------------- | 
|  | * (C) Copyright 2000 | 
|  | * Sysgo Real-Time Solutions GmbH | 
|  | * Klein-Winternheim, Germany | 
|  | *---------------------------------------------------------------------- | 
|  | */ | 
|  |  | 
|  | #include "bios.h" | 
|  |  | 
|  | /* | 
|  | * During it's initialization phase, before switching to protected | 
|  | * mode, the Linux Kernel makes a few BIOS calls. This won't work | 
|  | * if the board does not have a BIOS. | 
|  | * | 
|  | * This is a very minimalisic BIOS that supplies just enough | 
|  | * functionality to keep the Linux Kernel happy. It is NOT | 
|  | * a general purpose replacement for a real BIOS !! | 
|  | */ | 
|  |  | 
|  |  | 
|  | .section .bios, "ax" | 
|  | .code16 | 
|  | .org 0 | 
|  | /* a call to f000:0 should warmboot */ | 
|  | jmp	realmode_reset | 
|  |  | 
|  | .globl rm_int00 | 
|  | rm_int00: | 
|  | pushw	$0 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int01 | 
|  | rm_int01: | 
|  | pushw	$1 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int02 | 
|  | rm_int02: | 
|  | pushw	$2 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int03 | 
|  | rm_int03: | 
|  | pushw	$3 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int04 | 
|  | rm_int04: | 
|  | pushw	$4 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int05 | 
|  | rm_int05: | 
|  | pushw	$5 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int06 | 
|  | rm_int06: | 
|  | pushw	$6 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int07 | 
|  | rm_int07: | 
|  | pushw	$7 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int08 | 
|  | rm_int08: | 
|  | pushw	$8 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int09 | 
|  | rm_int09: | 
|  | pushw	$9 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int0a | 
|  | rm_int0a: | 
|  | pushw	$10 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int0b | 
|  | rm_int0b: | 
|  | pushw	$11 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int0c | 
|  | rm_int0c: | 
|  | pushw	$12 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int0d | 
|  | rm_int0d: | 
|  | pushw	$13 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int0e | 
|  | rm_int0e: | 
|  | pushw	$14 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int0f | 
|  | rm_int0f: | 
|  | pushw	$15 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int10 | 
|  | rm_int10: | 
|  | pushw	$16 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int11 | 
|  | rm_int11: | 
|  | pushw	$17 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int12 | 
|  | rm_int12: | 
|  | pushw	$18 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int13 | 
|  | rm_int13: | 
|  | pushw	$19 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int14 | 
|  | rm_int14: | 
|  | pushw	$20 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int15 | 
|  | rm_int15: | 
|  | pushw	$21 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int16 | 
|  | rm_int16: | 
|  | pushw	$22 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int17 | 
|  | rm_int17: | 
|  | pushw	$23 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int18 | 
|  | rm_int18: | 
|  | pushw	$24 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int19 | 
|  | rm_int19: | 
|  | pushw	$25 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int1a | 
|  | rm_int1a: | 
|  | pushw	$26 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int1b | 
|  | rm_int1b: | 
|  | pushw	$27 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int1c | 
|  | rm_int1c: | 
|  | pushw	$28 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int1d | 
|  | rm_int1d: | 
|  | pushw	$29 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int1e | 
|  | rm_int1e: | 
|  | pushw	$30 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_int1f | 
|  | rm_int1f: | 
|  | pushw	$31 | 
|  | jmp	any_interrupt16 | 
|  | .globl rm_def_int | 
|  | rm_def_int: | 
|  | iret | 
|  |  | 
|  |  | 
|  | /* | 
|  | * All interrupt jumptable entries jump to here | 
|  | * after pushing the interrupt vector number onto the | 
|  | * stack. | 
|  | */ | 
|  | any_interrupt16: | 
|  | MAKE_BIOS_STACK | 
|  |  | 
|  | gs	movw	OFFS_VECTOR(%bp), %ax | 
|  | cmpw	$0x10, %ax | 
|  | je	Lint_10h | 
|  | cmpw	$0x11, %ax | 
|  | je	Lint_11h | 
|  | cmpw	$0x12, %ax | 
|  | je	Lint_12h | 
|  | cmpw	$0x13, %ax | 
|  | je	Lint_13h | 
|  | cmpw	$0x15, %ax | 
|  | je	Lint_15h | 
|  | cmpw	$0x16, %ax | 
|  | je	Lint_16h | 
|  | cmpw	$0x1a, %ax | 
|  | je	Lint_1ah | 
|  | movw	$0xffff, %ax | 
|  | jmp	Lout | 
|  | Lint_10h:					/* VGA BIOS services */ | 
|  | call	bios_10h | 
|  | jmp	Lout | 
|  | Lint_11h: | 
|  | call	bios_11h | 
|  | jmp	Lout | 
|  | Lint_12h: | 
|  | call	bios_12h | 
|  | jmp	Lout | 
|  | Lint_13h:					/* BIOS disk services */ | 
|  | call	bios_13h | 
|  | jmp	Lout | 
|  | Lint_15h:					/* Misc. BIOS services */ | 
|  | call	bios_15h | 
|  | jmp	Lout | 
|  | Lint_16h:					/* keyboard services */ | 
|  | call	bios_16h | 
|  | jmp	Lout | 
|  | Lint_1ah:					/* PCI bios */ | 
|  | call	bios_1ah | 
|  | jmp	Lout | 
|  | Lout: | 
|  | cmpw	$0, %ax | 
|  | je	Lhandeled | 
|  |  | 
|  | /* Insert code for unhandeled INTs here. | 
|  | * | 
|  | * ROLO prints a message to the console | 
|  | * (we could do that but then we're in 16bit mode | 
|  | * so we'll have to get back into 32bit mode | 
|  | * to use the console I/O routines (if we do this | 
|  | * we shuls make int 0x10 and int 0x16 work as well)) | 
|  | */ | 
|  | Lhandeled: | 
|  | RESTORE_CALLERS_STACK | 
|  | addw	$2,%sp				/* dump vector number */ | 
|  | iret					/* return from interrupt */ | 
|  |  | 
|  |  | 
|  | /* | 
|  | ************************************************************ | 
|  | * BIOS 	interrupt 10h -- VGA services | 
|  | ************************************************************ | 
|  | */ | 
|  | bios_10h: | 
|  | gs	movw	OFFS_AX(%bp), %ax | 
|  | shrw	$8, %ax | 
|  | cmpw	$0x3, %ax | 
|  | je	Lcur_pos | 
|  | cmpw	$0xf, %ax | 
|  | je	Lvid_state | 
|  | cmpw	$0x12, %ax | 
|  | je	Lvid_cfg | 
|  | movw	$0xffff, %ax | 
|  | ret | 
|  | Lcur_pos:					/* Read Cursor Position and Size */ | 
|  | gs	movw	$0, OFFS_CX(%bp) | 
|  | gs	movw	$0, OFFS_DX(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  | Lvid_state:					/* Get Video State */ | 
|  | gs	movw	$(80 << 8|0x03), OFFS_AX(%bp)	/* 80 columns, 80x25, 16 colors */ | 
|  | gs	movw	$0, OFFS_BX(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  | Lvid_cfg:	/* Video Subsystem Configuration (EGA/VGA) */ | 
|  | gs	movw	$0x10, OFFS_BX(%bp)		/* indicate CGA/MDA/HGA */ | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  |  | 
|  | /* | 
|  | ************************************************************ | 
|  | * BIOS interrupt 11h -- Equipment determination | 
|  | ************************************************************ | 
|  | */ | 
|  |  | 
|  | bios_11h: | 
|  | cs	movw	bios_equipment, %ax | 
|  | gs	movw	%ax, OFFS_AX(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  |  | 
|  | /* | 
|  | ************************************************************ | 
|  | * BIOS 	interrupt 12h -- Get Memory Size | 
|  | ************************************************************ | 
|  | */ | 
|  | bios_12h: | 
|  | cs	movw	ram_in_64kb_chunks, %ax | 
|  | cmpw	$0xa, %ax | 
|  | ja	b12_more_than_640k | 
|  | shlw	$6, %ax | 
|  | jmp	b12_return | 
|  | b12_more_than_640k: | 
|  | movw	$0x280, %ax | 
|  | b12_return: | 
|  | gs	movw	%ax, OFFS_AX(%bp)		/* return number of kilobytes in ax */ | 
|  |  | 
|  | gs	movw	OFFS_FLAGS(%bp), %ax | 
|  | andw	$0xfffe, %ax			/* clear carry -- function succeeded */ | 
|  | gs	movw	%ax, OFFS_FLAGS(%bp) | 
|  |  | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  |  | 
|  | /* | 
|  | ************************************************************ | 
|  | * BIOS interrupt 13h -- Disk services | 
|  | ************************************************************ | 
|  | */ | 
|  | bios_13h: | 
|  | gs	movw	OFFS_AX(%bp), %ax | 
|  | shrw	$8, %ax | 
|  | cmpw	$0x15, %ax | 
|  | je	Lfunc_15h | 
|  | movw	$0xffff, %ax | 
|  | ret | 
|  | Lfunc_15h: | 
|  | gs	movw	OFFS_AX(%bp), %ax | 
|  | andw	$0xff, %ax			/* return AH=0->drive not present */ | 
|  | gs	movw	%ax, OFFS_AX(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  |  | 
|  | /* | 
|  | *********************************************************** | 
|  | * BIOS interrupt 15h -- Miscellaneous services | 
|  | *********************************************************** | 
|  | */ | 
|  | bios_15h: | 
|  | gs	movw	OFFS_AX(%bp), %ax | 
|  | shrw	$8, %ax | 
|  | cmpw	$0xc0, %ax | 
|  | je	Lfunc_c0h | 
|  | cmpw	$0xe8, %ax | 
|  | je	Lfunc_e8h | 
|  | cmpw	$0x88, %ax | 
|  | je	Lfunc_88h | 
|  | movw	$0xffff, %ax | 
|  | ret | 
|  |  | 
|  | Lfunc_c0h: 					/* Return System Configuration Parameters (PS2 only) */ | 
|  | gs	movw	OFFS_FLAGS(%bp), %ax | 
|  | orw	$1, %ax				/* return carry -- function not supported */ | 
|  | gs	movw	%ax, OFFS_FLAGS(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  | Lfunc_e8h: | 
|  | gs	movw	OFFS_AX(%bp), %ax | 
|  | andw	$0xff, %ax | 
|  | cmpw	$1, %ax | 
|  | je	Lfunc_e801h | 
|  | gs	movw	OFFS_FLAGS(%bp), %ax | 
|  | orw	$1, %ax				/* return carry -- function not supported */ | 
|  | gs	movw	%ax, OFFS_FLAGS(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  | Lfunc_e801h:					/* Get memory size for >64M Configurations */ | 
|  | cs	movw	ram_in_64kb_chunks, %ax | 
|  | cmpw	$0x100, %ax | 
|  | ja	e801_more_than_16mb | 
|  | shlw	$6, %ax				/* multiply by 64 */ | 
|  | subw	$0x400, %ax			/* 1st meg does not count */ | 
|  |  | 
|  | gs	movw	%ax, OFFS_AX(%bp)   		/* return memory size between 1M and 16M in 1kb chunks in AX and CX */ | 
|  | gs	movw	%ax, OFFS_CX(%bp) | 
|  | gs	movw	$0, OFFS_BX(%bp)		/* set BX and DX to 0*/ | 
|  | gs	movw	$0, OFFS_DX(%bp) | 
|  | gs	movw	OFFS_FLAGS(%bp), %ax | 
|  | andw	$0xfffe, %ax			/* clear carry -- function succeeded */ | 
|  | gs	movw	%ax, OFFS_FLAGS(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  | e801_more_than_16mb: | 
|  | subw	$0x100, %ax			/* subtract 16MB */ | 
|  |  | 
|  | gs	movw	$0x3c00, OFFS_AX(%bp)		/* return 0x3c00 (16MB-1MB) in AX and CX */ | 
|  | gs	movw	$0x3c00, OFFS_CX(%bp) | 
|  | gs	movw	%ax, OFFS_BX(%bp)		/* set BX and DX to number of 64kb chunks above 16MB */ | 
|  | gs	movw	%ax, OFFS_DX(%bp) | 
|  |  | 
|  | gs	movw	OFFS_FLAGS(%bp), %ax | 
|  | andw	$0xfffe, %ax			/* clear carry -- function succeeded */ | 
|  | gs	movw	%ax, OFFS_FLAGS(%bp) | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  | Lfunc_88h: | 
|  | cs	movw	ram_in_64kb_chunks, %ax | 
|  | cmpw	$0x100, %ax | 
|  | jna	b88_not_more_than16 | 
|  | movw	$0x100, %ax | 
|  | b88_not_more_than16: | 
|  | shlw	$6, %ax | 
|  | subw	$0x400, %ax			/* 1st meg does not count */ | 
|  |  | 
|  | gs	movw	%ax, OFFS_AX(%bp)		/* return number of kilobytes between 16MB and 16MB in ax */ | 
|  |  | 
|  | gs	movw	OFFS_FLAGS(%bp), %ax | 
|  | andw	$0xfffe, %ax			/* clear carry -- function succeeded */ | 
|  | gs	movw	%ax, OFFS_FLAGS(%bp) | 
|  |  | 
|  | xorw	%ax, %ax | 
|  | ret | 
|  |  | 
|  |  | 
|  | /* | 
|  | ************************************************************ | 
|  | * BIOS interrupt 16h -- keyboard services | 
|  | ************************************************************ | 
|  | */ | 
|  | bios_16h: | 
|  | gs	movw	OFFS_AX(%bp), %ax | 
|  | shrw	$8, %ax | 
|  | cmpw	$0x03, %ax | 
|  | je	Lfunc_03h | 
|  | movw	$0xffff, %ax | 
|  | ret | 
|  | Lfunc_03h: | 
|  | xorw	%ax, %ax			/* do nothing -- function not supported */ | 
|  | ret | 
|  |  | 
|  | /* | 
|  | ************************************************************ | 
|  | * BIOS interrupt 1ah -- PCI bios | 
|  | ************************************************************ | 
|  | */ | 
|  | bios_1ah: | 
|  | gs	movw	OFFS_AX(%bp), %ax | 
|  | cmpb	$0xb1, %ah | 
|  | je	Lfunc_b1h | 
|  | movw	$0xffff, %ax | 
|  | ret | 
|  | Lfunc_b1h: | 
|  | call	realmode_pci_bios | 
|  | xorw	%ax, %ax			/* do nothing -- function not supported */ | 
|  | ret | 
|  |  | 
|  |  | 
|  | .globl ram_in_64kb_chunks | 
|  | ram_in_64kb_chunks: | 
|  | .word 	0 | 
|  |  | 
|  | .globl bios_equipment | 
|  | bios_equipment: | 
|  | .word 	0 |