mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			533 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			533 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/*
 | 
						|
 * (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
 | 
						|
.hidden rm_int00
 | 
						|
.type rm_int00, @function
 | 
						|
rm_int00:
 | 
						|
	pushw	$0
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int01
 | 
						|
.hidden rm_int01
 | 
						|
.type rm_int01, @function
 | 
						|
rm_int01:
 | 
						|
	pushw	$1
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int02
 | 
						|
.hidden rm_int02
 | 
						|
.type rm_int02, @function
 | 
						|
rm_int02:
 | 
						|
	pushw	$2
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int03
 | 
						|
.hidden rm_int03
 | 
						|
.type rm_int03, @function
 | 
						|
rm_int03:
 | 
						|
	pushw	$3
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int04
 | 
						|
.hidden rm_int04
 | 
						|
.type rm_int04, @function
 | 
						|
rm_int04:
 | 
						|
	pushw	$4
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int05
 | 
						|
.hidden rm_int05
 | 
						|
.type rm_int05, @function
 | 
						|
rm_int05:
 | 
						|
	pushw	$5
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int06
 | 
						|
.hidden rm_int06
 | 
						|
.type rm_int06, @function
 | 
						|
rm_int06:
 | 
						|
	pushw	$6
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int07
 | 
						|
.hidden rm_int07
 | 
						|
.type rm_int07, @function
 | 
						|
rm_int07:
 | 
						|
	pushw	$7
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int08
 | 
						|
.hidden rm_int08
 | 
						|
.type rm_int08, @function
 | 
						|
rm_int08:
 | 
						|
	pushw	$8
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int09
 | 
						|
.hidden rm_int09
 | 
						|
.type rm_int09, @function
 | 
						|
rm_int09:
 | 
						|
	pushw	$9
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int0a
 | 
						|
.hidden rm_int0a
 | 
						|
.type rm_int0a, @function
 | 
						|
rm_int0a:
 | 
						|
	pushw	$10
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int0b
 | 
						|
.hidden rm_int0b
 | 
						|
.type rm_int0b, @function
 | 
						|
rm_int0b:
 | 
						|
	pushw	$11
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int0c
 | 
						|
.hidden rm_int0c
 | 
						|
.type rm_int0c, @function
 | 
						|
rm_int0c:
 | 
						|
	pushw	$12
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int0d
 | 
						|
.hidden rm_int0d
 | 
						|
.type rm_int0d, @function
 | 
						|
rm_int0d:
 | 
						|
	pushw	$13
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int0e
 | 
						|
.hidden rm_int0e
 | 
						|
.type rm_int0e, @function
 | 
						|
rm_int0e:
 | 
						|
	pushw	$14
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int0f
 | 
						|
.hidden rm_int0f
 | 
						|
.type rm_int0f, @function
 | 
						|
rm_int0f:
 | 
						|
	pushw	$15
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int10
 | 
						|
.hidden rm_int10
 | 
						|
.type rm_int10, @function
 | 
						|
rm_int10:
 | 
						|
	pushw	$16
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int11
 | 
						|
.hidden rm_int11
 | 
						|
.type rm_int11, @function
 | 
						|
rm_int11:
 | 
						|
	pushw	$17
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int12
 | 
						|
.hidden rm_int12
 | 
						|
.type rm_int12, @function
 | 
						|
rm_int12:
 | 
						|
	pushw	$18
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int13
 | 
						|
.hidden rm_int13
 | 
						|
.type rm_int13, @function
 | 
						|
rm_int13:
 | 
						|
	pushw	$19
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int14
 | 
						|
.hidden rm_int14
 | 
						|
.type rm_int14, @function
 | 
						|
rm_int14:
 | 
						|
	pushw	$20
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int15
 | 
						|
.hidden rm_int15
 | 
						|
.type rm_int15, @function
 | 
						|
rm_int15:
 | 
						|
	pushw	$21
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int16
 | 
						|
.hidden rm_int16
 | 
						|
.type rm_int16, @function
 | 
						|
rm_int16:
 | 
						|
	pushw	$22
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int17
 | 
						|
.hidden rm_int17
 | 
						|
.type rm_int17, @function
 | 
						|
rm_int17:
 | 
						|
	pushw	$23
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int18
 | 
						|
.hidden rm_int18
 | 
						|
.type rm_int18, @function
 | 
						|
rm_int18:
 | 
						|
	pushw	$24
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int19
 | 
						|
.hidden rm_int19
 | 
						|
.type rm_int19, @function
 | 
						|
rm_int19:
 | 
						|
	pushw	$25
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int1a
 | 
						|
.hidden rm_int1a
 | 
						|
.type rm_int1a, @function
 | 
						|
rm_int1a:
 | 
						|
	pushw	$26
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int1b
 | 
						|
.hidden rm_int1b
 | 
						|
.type rm_int1b, @function
 | 
						|
rm_int1b:
 | 
						|
	pushw	$27
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int1c
 | 
						|
.hidden rm_int1c
 | 
						|
.type rm_int1c, @function
 | 
						|
rm_int1c:
 | 
						|
	pushw	$28
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int1d
 | 
						|
.hidden rm_int1d
 | 
						|
.type rm_int1d, @function
 | 
						|
rm_int1d:
 | 
						|
	pushw	$29
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int1e
 | 
						|
.hidden rm_int1e
 | 
						|
.type rm_int1e, @function
 | 
						|
rm_int1e:
 | 
						|
	pushw	$30
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_int1f
 | 
						|
.hidden rm_int1f
 | 
						|
.type rm_int1f, @function
 | 
						|
rm_int1f:
 | 
						|
	pushw	$31
 | 
						|
	jmp	any_interrupt16
 | 
						|
.globl rm_def_int
 | 
						|
.hidden rm_def_int
 | 
						|
.type rm_def_int, @function
 | 
						|
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
 | 
						|
.hidden ram_in_64kb_chunks
 | 
						|
.type ram_in_64kb_chunks, @function
 | 
						|
ram_in_64kb_chunks:
 | 
						|
	.word	0
 | 
						|
 | 
						|
.globl bios_equipment
 | 
						|
.hidden bios_equipment
 | 
						|
.type bios_equipment, @function
 | 
						|
bios_equipment:
 | 
						|
	.word	0
 |