This code is pretty old and we want to support only 32-bit systems now. Signed-off-by: Simon Glass <sjg@chromium.org> Acked-by: Graeme Russ <graeme.russ@gmail.com>master
parent
588a13f742
commit
96dfc0633a
@ -1,36 +0,0 @@ |
|||||||
/*
|
|
||||||
* (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 |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef __ASM_REALMODE_H_ |
|
||||||
#define __ASM_REALMODE_H_ |
|
||||||
#include <asm/ptrace.h> |
|
||||||
|
|
||||||
extern ulong __realmode_start; |
|
||||||
extern ulong __realmode_size; |
|
||||||
extern char realmode_enter; |
|
||||||
|
|
||||||
int bios_setup(void); |
|
||||||
int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out); |
|
||||||
int enter_realmode_int(u8 lvl, struct pt_regs *in, struct pt_regs *out); |
|
||||||
|
|
||||||
#endif |
|
@ -1,569 +0,0 @@ |
|||||||
/* |
|
||||||
* (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 should make |
|
||||||
* int 0x10 and int 0x16 work as well) |
|
||||||
*/ |
|
||||||
Lhandeled: |
|
||||||
RESTORE_CALLERS_STACK |
|
||||||
|
|
||||||
/* dump vector number */ |
|
||||||
addw $2,%sp |
|
||||||
|
|
||||||
/* return from interrupt */ |
|
||||||
iret |
|
||||||
|
|
||||||
/* |
|
||||||
************************************************************ |
|
||||||
* 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 - 80 columns, 80x25, 16 colors */ |
|
||||||
gs movw $(80 << 8|0x03), OFFS_AX(%bp) |
|
||||||
gs movw $0, OFFS_BX(%bp) |
|
||||||
xorw %ax, %ax |
|
||||||
ret |
|
||||||
Lvid_cfg: |
|
||||||
/* Video Subsystem Configuration (EGA/VGA) - indicate CGA/MDA/HGA */ |
|
||||||
gs movw $0x10, OFFS_BX(%bp) |
|
||||||
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: |
|
||||||
/* return number of kilobytes in ax */ |
|
||||||
gs movw %ax, OFFS_AX(%bp) |
|
||||||
|
|
||||||
gs movw OFFS_FLAGS(%bp), %ax |
|
||||||
|
|
||||||
/* clear carry -- function succeeded */ |
|
||||||
andw $0xfffe, %ax |
|
||||||
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 |
|
||||||
|
|
||||||
/* return AH=0->drive not present */ |
|
||||||
andw $0x00ff, %ax |
|
||||||
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 |
|
||||||
|
|
||||||
/* return carry -- function not supported */ |
|
||||||
orw $1, %ax |
|
||||||
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 |
|
||||||
|
|
||||||
/* return carry -- function not supported */ |
|
||||||
orw $1, %ax |
|
||||||
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 |
|
||||||
|
|
||||||
/* multiply by 64 */ |
|
||||||
shlw $6, %ax |
|
||||||
|
|
||||||
/* 1st meg does not count */ |
|
||||||
subw $0x400, %ax |
|
||||||
|
|
||||||
/* return memory size between 1M and 16M in 1kb chunks in AX and CX */ |
|
||||||
gs movw %ax, OFFS_AX(%bp) |
|
||||||
gs movw %ax, OFFS_CX(%bp) |
|
||||||
|
|
||||||
/* set BX and DX to 0*/ |
|
||||||
gs movw $0, OFFS_BX(%bp) |
|
||||||
gs movw $0, OFFS_DX(%bp) |
|
||||||
gs movw OFFS_FLAGS(%bp), %ax |
|
||||||
|
|
||||||
/* clear carry -- function succeeded */ |
|
||||||
andw $0xfffe, %ax |
|
||||||
gs movw %ax, OFFS_FLAGS(%bp) |
|
||||||
xorw %ax, %ax |
|
||||||
ret |
|
||||||
|
|
||||||
e801_more_than_16mb: |
|
||||||
/* subtract 16MB */ |
|
||||||
subw $0x100, %ax |
|
||||||
|
|
||||||
/* return 0x3c00 (16MB-1MB) in AX and CX */ |
|
||||||
gs movw $0x3c00, OFFS_AX(%bp) |
|
||||||
gs movw $0x3c00, OFFS_CX(%bp) |
|
||||||
|
|
||||||
/* set BX and DX to number of 64kb chunks above 16MB */ |
|
||||||
gs movw %ax, OFFS_BX(%bp) |
|
||||||
gs movw %ax, OFFS_DX(%bp) |
|
||||||
|
|
||||||
gs movw OFFS_FLAGS(%bp), %ax |
|
||||||
|
|
||||||
/* clear carry -- function succeeded */ |
|
||||||
andw $0xfffe, %ax |
|
||||||
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 |
|
||||||
|
|
||||||
/* 1st meg does not count */ |
|
||||||
subw $0x400, %ax |
|
||||||
|
|
||||||
/* return number of kilobytes between 16MB and 16MB in ax */ |
|
||||||
gs movw %ax, OFFS_AX(%bp) |
|
||||||
|
|
||||||
gs movw OFFS_FLAGS(%bp), %ax |
|
||||||
|
|
||||||
/* clear carry -- function succeeded */ |
|
||||||
andw $0xfffe, %ax |
|
||||||
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: |
|
||||||
/* do nothing -- function not supported */ |
|
||||||
xorw %ax, %ax |
|
||||||
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 |
|
||||||
|
|
||||||
/* do nothing -- function not supported */ |
|
||||||
xorw %ax, %ax |
|
||||||
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
|
|
@ -1,447 +0,0 @@ |
|||||||
/* |
|
||||||
* (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 |
|
||||||
*/ |
|
||||||
|
|
||||||
/* |
|
||||||
* x86 realmode assembly implementation of a PCI BIOS |
|
||||||
* for platforms that use one PCI hose and configuration |
|
||||||
* access type 1. (The common case for low-end PC's) |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "bios.h" |
|
||||||
|
|
||||||
#define PCI_BIOS_DEBUG |
|
||||||
|
|
||||||
.section .bios, "ax" |
|
||||||
.code16 |
|
||||||
.globl realmode_pci_bios_call_entry
|
|
||||||
.hidden realmode_pci_bios_call_entry
|
|
||||||
.type realmode_pci_bios_call_entry, @function
|
|
||||||
realmode_pci_bios_call_entry: |
|
||||||
MAKE_BIOS_STACK |
|
||||||
call realmode_pci_bios |
|
||||||
RESTORE_CALLERS_STACK |
|
||||||
ret |
|
||||||
|
|
||||||
|
|
||||||
.globl realmode_pci_bios
|
|
||||||
realmode_pci_bios: |
|
||||||
gs movw OFFS_AX(%bp), %ax |
|
||||||
cmpb $1, %al |
|
||||||
je pci_bios_present |
|
||||||
cmpb $2, %al |
|
||||||
je pci_bios_find_device |
|
||||||
cmpb $3, %al |
|
||||||
je pci_bios_find_class |
|
||||||
cmpb $6, %al |
|
||||||
je pci_bios_generate_special_cycle |
|
||||||
cmpb $8, %al |
|
||||||
je pci_bios_read_cfg_byte |
|
||||||
cmpb $9, %al |
|
||||||
je pci_bios_read_cfg_word |
|
||||||
cmpb $10, %al |
|
||||||
je pci_bios_read_cfg_dword |
|
||||||
cmpb $11, %al |
|
||||||
je pci_bios_write_cfg_byte |
|
||||||
cmpb $12, %al |
|
||||||
je pci_bios_write_cfg_word |
|
||||||
cmpb $13, %al |
|
||||||
je pci_bios_write_cfg_dword |
|
||||||
cmpb $14, %al |
|
||||||
je pci_bios_get_irq_routing |
|
||||||
cmpb $15, %al |
|
||||||
je pci_bios_set_irq |
|
||||||
jmp unknown_function |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_present: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_present |
|
||||||
#endif |
|
||||||
movl $0x20494350, %eax |
|
||||||
gs movl %eax, OFFS_EDX(%bp) |
|
||||||
|
|
||||||
/* We support cfg type 1 version 2.10 */ |
|
||||||
movb $0x01, %al |
|
||||||
gs movb %al, OFFS_AL(%bp) |
|
||||||
movw $0x0210, %ax |
|
||||||
gs movw %ax, OFFS_BX(%bp) |
|
||||||
|
|
||||||
/* last bus number */ |
|
||||||
cs movb pci_last_bus, %al |
|
||||||
gs movb %al, OFFS_CL(%bp) |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
/* device 0-31, function 0-7 */ |
|
||||||
pci_bios_find_device: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_find_device |
|
||||||
#endif |
|
||||||
gs movw OFFS_CX(%bp), %di |
|
||||||
shll $16, %edi |
|
||||||
gs movw OFFS_DX(%bp), %di |
|
||||||
/* edi now holds device in upper 16 bits and vendor in lower 16 bits */ |
|
||||||
|
|
||||||
gs movw OFFS_SI(%bp), %si |
|
||||||
|
|
||||||
/* start at bus 0 dev 0 function 0 */ |
|
||||||
xorw %bx, %bx |
|
||||||
pfd_loop: |
|
||||||
/* dword 0 is vendor/device */ |
|
||||||
xorw %ax, %ax |
|
||||||
call __pci_bios_select_register |
|
||||||
movw $0xcfc, %dx |
|
||||||
inl %dx, %eax |
|
||||||
|
|
||||||
/* our device ? */ |
|
||||||
cmpl %edi, %eax |
|
||||||
je pfd_found_one |
|
||||||
pfd_next_dev: |
|
||||||
/* check for multi function devices */ |
|
||||||
movw %bx, %ax |
|
||||||
andw $3, %ax |
|
||||||
jnz pfd_function_not_zero |
|
||||||
movw $0x000c, %ax |
|
||||||
call __pci_bios_select_register |
|
||||||
movw $0xcfe, %dx |
|
||||||
inb %dx, %al |
|
||||||
andb $0x80, %al |
|
||||||
jz pfd_not_multi_function |
|
||||||
pfd_function_not_zero: |
|
||||||
/* next function, overflows in to device number, then bus number */ |
|
||||||
incw %bx |
|
||||||
jmp pfd_check_bus |
|
||||||
|
|
||||||
pfd_not_multi_function: |
|
||||||
/* remove function bits */ |
|
||||||
andw $0xfff8, %bx |
|
||||||
|
|
||||||
/* next device, overflows in to bus number */ |
|
||||||
addw $0x0008, %bx |
|
||||||
pfd_check_bus: |
|
||||||
cs movb pci_last_bus, %ah |
|
||||||
cmpb %ah, %bh |
|
||||||
ja pfd_not_found |
|
||||||
jmp pfd_loop |
|
||||||
pfd_found_one: |
|
||||||
decw %si |
|
||||||
js pfd_done |
|
||||||
jmp pfd_next_dev |
|
||||||
|
|
||||||
pfd_done: |
|
||||||
gs movw %bx, OFFS_BX(%bp) |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
pfd_not_found: |
|
||||||
/* device not found */ |
|
||||||
movb $0x86, %ah |
|
||||||
jmp set_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_find_class: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_find_class |
|
||||||
#endif |
|
||||||
gs movl OFFS_ECX(%bp), %edi |
|
||||||
|
|
||||||
/* edi now holds class-code in lower 24 bits */ |
|
||||||
andl $0x00ffffff, %edi |
|
||||||
gs movw OFFS_SI(%bp), %si |
|
||||||
|
|
||||||
/* start at bus 0 dev 0 function 0 */ |
|
||||||
xorw %bx, %bx |
|
||||||
pfc_loop: |
|
||||||
/* dword 8 is class-code high 24bits */ |
|
||||||
movw $8, %ax |
|
||||||
call __pci_bios_select_register |
|
||||||
movw $0xcfc, %dx |
|
||||||
inl %dx, %eax |
|
||||||
shrl $8, %eax |
|
||||||
andl $0x00ffffff, %eax |
|
||||||
|
|
||||||
/* our device ? */ |
|
||||||
cmpl %edi, %eax |
|
||||||
je pfc_found_one |
|
||||||
pfc_next_dev: |
|
||||||
/* check for multi function devices */ |
|
||||||
andw $3, %bx |
|
||||||
jnz pfc_function_not_zero |
|
||||||
movw $0x000c, %ax |
|
||||||
call __pci_bios_select_register |
|
||||||
movw $0xcfe, %dx |
|
||||||
inb %dx, %al |
|
||||||
andb $0x80, %al |
|
||||||
jz pfc_not_multi_function |
|
||||||
pfc_function_not_zero: |
|
||||||
/* next function, overflows in to device number, then bus number */ |
|
||||||
incw %bx |
|
||||||
jmp pfc_check_bus |
|
||||||
|
|
||||||
pfc_not_multi_function: |
|
||||||
/* remove function bits */ |
|
||||||
andw $0xfff8, %bx |
|
||||||
|
|
||||||
/* next device, overflows in to bus number */ |
|
||||||
addw $0x0008, %bx |
|
||||||
pfc_check_bus: |
|
||||||
cs movb pci_last_bus, %ah |
|
||||||
cmpb %ah, %bh |
|
||||||
ja pfc_not_found |
|
||||||
jmp pfc_loop |
|
||||||
pfc_found_one: |
|
||||||
decw %si |
|
||||||
js pfc_done |
|
||||||
jmp pfc_next_dev |
|
||||||
|
|
||||||
pfc_done: |
|
||||||
gs movw %bx, OFFS_BX(%bp) |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
pfc_not_found: |
|
||||||
/* device not found */ |
|
||||||
movb $0x86, %ah |
|
||||||
jmp set_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_generate_special_cycle: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_generate_special_cycle |
|
||||||
#endif |
|
||||||
/* function not supported */ |
|
||||||
movb $0x81, %ah |
|
||||||
jmp set_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_read_cfg_byte: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_read_cfg_byte |
|
||||||
#endif |
|
||||||
call pci_bios_select_register |
|
||||||
gs movw OFFS_DI(%bp), %dx |
|
||||||
andw $3, %dx |
|
||||||
addw $0xcfc, %dx |
|
||||||
inb %dx, %al |
|
||||||
gs movb %al, OFFS_CL(%bp) |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_read_cfg_word: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_read_cfg_word |
|
||||||
#endif |
|
||||||
call pci_bios_select_register |
|
||||||
gs movw OFFS_DI(%bp), %dx |
|
||||||
andw $2, %dx |
|
||||||
addw $0xcfc, %dx |
|
||||||
inw %dx, %ax |
|
||||||
gs movw %ax, OFFS_CX(%bp) |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_read_cfg_dword: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_read_cfg_dword |
|
||||||
#endif |
|
||||||
call pci_bios_select_register |
|
||||||
movw $0xcfc, %dx |
|
||||||
inl %dx, %eax |
|
||||||
gs movl %eax, OFFS_ECX(%bp) |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_write_cfg_byte: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_write_cfg_byte |
|
||||||
#endif |
|
||||||
call pci_bios_select_register |
|
||||||
gs movw OFFS_DI(%bp), %dx |
|
||||||
gs movb OFFS_CL(%bp), %al |
|
||||||
andw $3, %dx |
|
||||||
addw $0xcfc, %dx |
|
||||||
outb %al, %dx |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_write_cfg_word: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_write_cfg_word |
|
||||||
#endif |
|
||||||
call pci_bios_select_register |
|
||||||
gs movw OFFS_DI(%bp), %dx |
|
||||||
gs movw OFFS_CX(%bp), %ax |
|
||||||
andw $2, %dx |
|
||||||
addw $0xcfc, %dx |
|
||||||
outw %ax, %dx |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_write_cfg_dword: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_write_cfg_dword |
|
||||||
#endif |
|
||||||
call pci_bios_select_register |
|
||||||
gs movl OFFS_ECX(%bp), %eax |
|
||||||
movw $0xcfc, %dx |
|
||||||
outl %eax, %dx |
|
||||||
jmp clear_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_get_irq_routing: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_get_irq_routing |
|
||||||
#endif |
|
||||||
/* function not supported */ |
|
||||||
movb $0x81, %ah |
|
||||||
jmp set_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_set_irq: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_set_irq |
|
||||||
#endif |
|
||||||
/* function not supported */ |
|
||||||
movb $0x81, %ah |
|
||||||
jmp set_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
unknown_function: |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
cs incl num_pci_bios_unknown_function |
|
||||||
#endif |
|
||||||
/* function not supported */ |
|
||||||
movb $0x81, %ah |
|
||||||
jmp set_carry |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
pci_bios_select_register: |
|
||||||
gs movw OFFS_BX(%bp), %bx |
|
||||||
gs movw OFFS_DI(%bp), %ax |
|
||||||
/* destroys eax, dx */ |
|
||||||
__pci_bios_select_register: |
|
||||||
/* BX holds device id, AX holds register index */ |
|
||||||
pushl %ebx |
|
||||||
andl $0xfc, %eax |
|
||||||
andl $0xffff, %ebx |
|
||||||
shll $8, %ebx |
|
||||||
orl %ebx, %eax |
|
||||||
orl $0x80000000, %eax |
|
||||||
movw $0xcf8, %dx |
|
||||||
outl %eax, %dx |
|
||||||
popl %ebx |
|
||||||
ret |
|
||||||
|
|
||||||
|
|
||||||
clear_carry: |
|
||||||
gs movw OFFS_FLAGS(%bp), %ax |
|
||||||
|
|
||||||
/* clear carry -- function succeeded */ |
|
||||||
andw $0xfffe, %ax |
|
||||||
gs movw %ax, OFFS_FLAGS(%bp) |
|
||||||
xorw %ax, %ax |
|
||||||
gs movb %ah, OFFS_AH(%bp) |
|
||||||
ret |
|
||||||
|
|
||||||
set_carry: |
|
||||||
gs movb %ah, OFFS_AH(%bp) |
|
||||||
gs movw OFFS_FLAGS(%bp), %ax |
|
||||||
|
|
||||||
/* return carry -- function not supported */ |
|
||||||
orw $1, %ax |
|
||||||
gs movw %ax, OFFS_FLAGS(%bp) |
|
||||||
movw $-1, %ax |
|
||||||
ret |
|
||||||
|
|
||||||
/*****************************************************************************/ |
|
||||||
|
|
||||||
.globl pci_last_bus
|
|
||||||
pci_last_bus: |
|
||||||
.byte 0
|
|
||||||
|
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
.globl num_pci_bios_present
|
|
||||||
num_pci_bios_present: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_find_device
|
|
||||||
num_pci_bios_find_device: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_find_class
|
|
||||||
num_pci_bios_find_class: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_generate_special_cycle
|
|
||||||
num_pci_bios_generate_special_cycle: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_read_cfg_byte
|
|
||||||
num_pci_bios_read_cfg_byte: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_read_cfg_word
|
|
||||||
num_pci_bios_read_cfg_word: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_read_cfg_dword
|
|
||||||
num_pci_bios_read_cfg_dword: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_write_cfg_byte
|
|
||||||
num_pci_bios_write_cfg_byte: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_write_cfg_word
|
|
||||||
num_pci_bios_write_cfg_word: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_write_cfg_dword
|
|
||||||
num_pci_bios_write_cfg_dword: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_get_irq_routing
|
|
||||||
num_pci_bios_get_irq_routing: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_set_irq
|
|
||||||
num_pci_bios_set_irq: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
.globl num_pci_bios_unknown_function
|
|
||||||
num_pci_bios_unknown_function: |
|
||||||
.long 0
|
|
||||||
#endif |
|
@ -1,179 +0,0 @@ |
|||||||
/*
|
|
||||||
* (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 |
|
||||||
*/ |
|
||||||
|
|
||||||
/*
|
|
||||||
* Partly based on msbios.c from rolo 1.6: |
|
||||||
*---------------------------------------------------------------------- |
|
||||||
* (C) Copyright 2000 |
|
||||||
* Sysgo Real-Time Solutions GmbH |
|
||||||
* Klein-Winternheim, Germany |
|
||||||
*---------------------------------------------------------------------- |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <common.h> |
|
||||||
#include <pci.h> |
|
||||||
#include <asm/realmode.h> |
|
||||||
#include <asm/io.h> |
|
||||||
#include "bios.h" |
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR; |
|
||||||
|
|
||||||
#define NUMVECTS 256 |
|
||||||
|
|
||||||
static int set_jmp_vector(int entry_point, void *target) |
|
||||||
{ |
|
||||||
if (entry_point & ~0xffff) |
|
||||||
return -1; |
|
||||||
|
|
||||||
if (((u32)target - 0xf0000) & ~0xffff) |
|
||||||
return -1; |
|
||||||
|
|
||||||
printf("set_jmp_vector: 0xf000:%04x -> %p\n", |
|
||||||
entry_point, target); |
|
||||||
|
|
||||||
/* jmp opcode */ |
|
||||||
writeb(0xea, 0xf0000 + entry_point); |
|
||||||
|
|
||||||
/* offset */ |
|
||||||
writew(((u32)target-0xf0000), 0xf0000 + entry_point + 1); |
|
||||||
|
|
||||||
/* segment */ |
|
||||||
writew(0xf000, 0xf0000 + entry_point + 3); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
/* Install an interrupt vector */ |
|
||||||
static void setvector(int vector, u16 segment, void *handler) |
|
||||||
{ |
|
||||||
u16 *ptr = (u16 *)(vector * 4); |
|
||||||
ptr[0] = ((u32)handler - (segment << 4)) & 0xffff; |
|
||||||
ptr[1] = segment; |
|
||||||
|
|
||||||
#if 0 |
|
||||||
printf("setvector: int%02x -> %04x:%04x\n", |
|
||||||
vector, ptr[1], ptr[0]); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
int bios_setup(void) |
|
||||||
{ |
|
||||||
/* The BIOS section is not relocated and still in the ROM. */ |
|
||||||
ulong bios_start = (ulong)&__bios_start; |
|
||||||
ulong bios_size = (ulong)&__bios_size; |
|
||||||
|
|
||||||
static int done; |
|
||||||
int vector; |
|
||||||
#ifdef CONFIG_PCI |
|
||||||
struct pci_controller *pri_hose; |
|
||||||
#endif |
|
||||||
if (done) |
|
||||||
return 0; |
|
||||||
|
|
||||||
done = 1; |
|
||||||
|
|
||||||
if (bios_size > 65536) { |
|
||||||
printf("BIOS too large (%ld bytes, max is 65536)\n", |
|
||||||
bios_size); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
memcpy(BIOS_BASE, (void *)bios_start, bios_size); |
|
||||||
|
|
||||||
/* clear bda */ |
|
||||||
memset(BIOS_DATA, 0, BIOS_DATA_SIZE); |
|
||||||
|
|
||||||
/* enter some values to the bda */ |
|
||||||
writew(0x3f8, BIOS_DATA); /* com1 addr */ |
|
||||||
writew(0x2f8, BIOS_DATA+2); /* com2 addr */ |
|
||||||
writew(0x3e8, BIOS_DATA+4); /* com3 addr */ |
|
||||||
writew(0x2e8, BIOS_DATA+6); /* com4 addr */ |
|
||||||
writew(0x278, BIOS_DATA+8); /* lpt1 addr */ |
|
||||||
/*
|
|
||||||
* The kernel wants to read the base memory size |
|
||||||
* from 40:13. Put a zero there to avoid an error message |
|
||||||
*/ |
|
||||||
writew(0, BIOS_DATA+0x13); /* base memory size */ |
|
||||||
|
|
||||||
|
|
||||||
/* setup realmode interrupt vectors */ |
|
||||||
for (vector = 0; vector < NUMVECTS; vector++) |
|
||||||
setvector(vector, BIOS_CS, &rm_def_int); |
|
||||||
|
|
||||||
setvector(0x00, BIOS_CS, &rm_int00); |
|
||||||
setvector(0x01, BIOS_CS, &rm_int01); |
|
||||||
setvector(0x02, BIOS_CS, &rm_int02); |
|
||||||
setvector(0x03, BIOS_CS, &rm_int03); |
|
||||||
setvector(0x04, BIOS_CS, &rm_int04); |
|
||||||
setvector(0x05, BIOS_CS, &rm_int05); |
|
||||||
setvector(0x06, BIOS_CS, &rm_int06); |
|
||||||
setvector(0x07, BIOS_CS, &rm_int07); |
|
||||||
setvector(0x08, BIOS_CS, &rm_int08); |
|
||||||
setvector(0x09, BIOS_CS, &rm_int09); |
|
||||||
setvector(0x0a, BIOS_CS, &rm_int0a); |
|
||||||
setvector(0x0b, BIOS_CS, &rm_int0b); |
|
||||||
setvector(0x0c, BIOS_CS, &rm_int0c); |
|
||||||
setvector(0x0d, BIOS_CS, &rm_int0d); |
|
||||||
setvector(0x0e, BIOS_CS, &rm_int0e); |
|
||||||
setvector(0x0f, BIOS_CS, &rm_int0f); |
|
||||||
setvector(0x10, BIOS_CS, &rm_int10); |
|
||||||
setvector(0x11, BIOS_CS, &rm_int11); |
|
||||||
setvector(0x12, BIOS_CS, &rm_int12); |
|
||||||
setvector(0x13, BIOS_CS, &rm_int13); |
|
||||||
setvector(0x14, BIOS_CS, &rm_int14); |
|
||||||
setvector(0x15, BIOS_CS, &rm_int15); |
|
||||||
setvector(0x16, BIOS_CS, &rm_int16); |
|
||||||
setvector(0x17, BIOS_CS, &rm_int17); |
|
||||||
setvector(0x18, BIOS_CS, &rm_int18); |
|
||||||
setvector(0x19, BIOS_CS, &rm_int19); |
|
||||||
setvector(0x1a, BIOS_CS, &rm_int1a); |
|
||||||
setvector(0x1b, BIOS_CS, &rm_int1b); |
|
||||||
setvector(0x1c, BIOS_CS, &rm_int1c); |
|
||||||
setvector(0x1d, BIOS_CS, &rm_int1d); |
|
||||||
setvector(0x1e, BIOS_CS, &rm_int1e); |
|
||||||
setvector(0x1f, BIOS_CS, &rm_int1f); |
|
||||||
|
|
||||||
set_jmp_vector(0xfff0, &realmode_reset); |
|
||||||
set_jmp_vector(0xfe6e, &realmode_pci_bios_call_entry); |
|
||||||
|
|
||||||
/* fill in data area */ |
|
||||||
RELOC_16_WORD(0xf000, ram_in_64kb_chunks) = gd->ram_size >> 16; |
|
||||||
RELOC_16_WORD(0xf000, bios_equipment) = 0; /* FixMe */ |
|
||||||
|
|
||||||
/* If we assume only one PCI hose, this PCI hose
|
|
||||||
* will own PCI bus #0, and the last PCI bus of |
|
||||||
* that PCI hose will be the last PCI bus in the |
|
||||||
* system. |
|
||||||
* (This, ofcause break on multi hose systems, |
|
||||||
* but our PCI BIOS only support one hose anyway) |
|
||||||
*/ |
|
||||||
#ifdef CONFIG_PCI |
|
||||||
pri_hose = pci_bus_to_hose(0); |
|
||||||
if (NULL != pri_hose) { |
|
||||||
/* fill in last pci bus number for use by the realmode
|
|
||||||
* PCI BIOS */ |
|
||||||
RELOC_16_BYTE(0xf000, pci_last_bus) = pri_hose->last_busno; |
|
||||||
} |
|
||||||
#endif |
|
||||||
return 0; |
|
||||||
} |
|
@ -1,93 +0,0 @@ |
|||||||
/*
|
|
||||||
* (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 |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <common.h> |
|
||||||
#include <asm/io.h> |
|
||||||
#include <asm/ptrace.h> |
|
||||||
#include <asm/realmode.h> |
|
||||||
|
|
||||||
#define REALMODE_MAILBOX ((char *)0xe00) |
|
||||||
|
|
||||||
int realmode_setup(void) |
|
||||||
{ |
|
||||||
/* The realmode section is not relocated and still in the ROM. */ |
|
||||||
ulong realmode_start = (ulong)&__realmode_start; |
|
||||||
ulong realmode_size = (ulong)&__realmode_size; |
|
||||||
|
|
||||||
/* copy the realmode switch code */ |
|
||||||
if (realmode_size > (REALMODE_MAILBOX - (char *)REALMODE_BASE)) { |
|
||||||
printf("realmode switch too large (%ld bytes, max is %d)\n", |
|
||||||
realmode_size, |
|
||||||
(int)(REALMODE_MAILBOX - (char *)REALMODE_BASE)); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
memcpy((char *)REALMODE_BASE, (void *)realmode_start, realmode_size); |
|
||||||
asm("wbinvd\n"); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out) |
|
||||||
{ |
|
||||||
|
|
||||||
/* setup out thin bios emulation */ |
|
||||||
if (bios_setup()) |
|
||||||
return -1; |
|
||||||
|
|
||||||
if (realmode_setup()) |
|
||||||
return -1; |
|
||||||
|
|
||||||
in->eip = off; |
|
||||||
in->xcs = seg; |
|
||||||
if ((in->esp & 0xffff) < 4) |
|
||||||
printf("Warning: entering realmode with sp < 4 will fail\n"); |
|
||||||
|
|
||||||
memcpy(REALMODE_MAILBOX, in, sizeof(struct pt_regs)); |
|
||||||
asm("wbinvd\n"); |
|
||||||
|
|
||||||
__asm__ volatile ( |
|
||||||
"lcall $0x20,%0\n" : : "i" (&realmode_enter)); |
|
||||||
|
|
||||||
asm("wbinvd\n"); |
|
||||||
memcpy(out, REALMODE_MAILBOX, sizeof(struct pt_regs)); |
|
||||||
|
|
||||||
return out->eax; |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* This code is supposed to access a realmode interrupt |
|
||||||
* it does currently not work for me |
|
||||||
*/ |
|
||||||
int enter_realmode_int(u8 lvl, struct pt_regs *in, struct pt_regs *out) |
|
||||||
{ |
|
||||||
/* place two instructions at 0x700 */ |
|
||||||
writeb(0xcd, 0x700); /* int $lvl */ |
|
||||||
writeb(lvl, 0x701); |
|
||||||
writeb(0xcb, 0x702); /* lret */ |
|
||||||
asm("wbinvd\n"); |
|
||||||
|
|
||||||
enter_realmode(0x00, 0x700, in, out); |
|
||||||
|
|
||||||
return out->eflags & 0x00000001; |
|
||||||
} |
|
@ -1,232 +0,0 @@ |
|||||||
/* |
|
||||||
* (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 |
|
||||||
*/ |
|
||||||
|
|
||||||
/* 32bit -> 16bit -> 32bit mode switch code */ |
|
||||||
|
|
||||||
/* |
|
||||||
* Stack frame at 0xe00 |
|
||||||
* e00 ebx;
|
|
||||||
* e04 ecx;
|
|
||||||
* e08 edx;
|
|
||||||
* e0c esi;
|
|
||||||
* e10 edi;
|
|
||||||
* e14 ebp;
|
|
||||||
* e18 eax;
|
|
||||||
* e1c ds;
|
|
||||||
* e20 es;
|
|
||||||
* e24 fs;
|
|
||||||
* e28 gs;
|
|
||||||
* e2c orig_eax;
|
|
||||||
* e30 eip;
|
|
||||||
* e34 cs;
|
|
||||||
* e38 eflags;
|
|
||||||
* e3c esp;
|
|
||||||
* e40 ss;
|
|
||||||
*/ |
|
||||||
|
|
||||||
#define a32 .byte 0x67; /* address size prefix 32 */
|
|
||||||
#define o32 .byte 0x66; /* operand size prefix 32 */
|
|
||||||
|
|
||||||
.section .realmode, "ax" |
|
||||||
.code16 |
|
||||||
|
|
||||||
/* 16bit protected mode code here */ |
|
||||||
.globl realmode_enter
|
|
||||||
realmode_enter: |
|
||||||
o32 pusha |
|
||||||
o32 pushf |
|
||||||
cli |
|
||||||
sidt saved_idt |
|
||||||
sgdt saved_gdt |
|
||||||
movl %esp, %eax |
|
||||||
movl %eax, saved_protected_mode_esp |
|
||||||
|
|
||||||
movl $0x10, %eax |
|
||||||
movl %eax, %esp |
|
||||||
movw $0x28, %ax |
|
||||||
movw %ax, %ds |
|
||||||
movw %ax, %es |
|
||||||
movw %ax, %fs |
|
||||||
movw %ax, %gs |
|
||||||
|
|
||||||
lidt realmode_idt_ptr |
|
||||||
/* Go back into real mode by clearing PE to 0 */ |
|
||||||
movl %cr0, %eax |
|
||||||
andl $0x7ffffffe, %eax |
|
||||||
movl %eax, %cr0 |
|
||||||
|
|
||||||
/* switch to real mode */ |
|
||||||
ljmp $0x0,$do_realmode |
|
||||||
|
|
||||||
do_realmode: |
|
||||||
/* realmode code from here */ |
|
||||||
movw %cs,%ax |
|
||||||
movw %ax,%ds |
|
||||||
movw %ax,%es |
|
||||||
movw %ax,%fs |
|
||||||
movw %ax,%gs |
|
||||||
|
|
||||||
/* create a temporary stack */ |
|
||||||
movw $0xc0, %ax |
|
||||||
movw %ax, %ss |
|
||||||
movw $0x200, %ax |
|
||||||
movw %ax, %sp |
|
||||||
|
|
||||||
popl %ebx |
|
||||||
popl %ecx |
|
||||||
popl %edx |
|
||||||
popl %esi |
|
||||||
popl %edi |
|
||||||
popl %ebp |
|
||||||
popl %eax |
|
||||||
movl %eax, temp_eax |
|
||||||
popl %eax |
|
||||||
movw %ax, %ds |
|
||||||
popl %eax |
|
||||||
movw %ax, %es |
|
||||||
popl %eax |
|
||||||
movw %ax, %fs |
|
||||||
popl %eax |
|
||||||
movw %ax, %gs |
|
||||||
popl %eax /* orig_eax */ |
|
||||||
popl %eax |
|
||||||
cs movw %ax, temp_ip |
|
||||||
popl %eax |
|
||||||
cs movw %ax, temp_cs |
|
||||||
o32 popf |
|
||||||
popl %eax |
|
||||||
popw %ss |
|
||||||
movl %eax, %esp |
|
||||||
cs movl temp_eax, %eax |
|
||||||
|
|
||||||
/* self-modifying code, better flush the cache */ |
|
||||||
wbinvd |
|
||||||
|
|
||||||
.byte 0x9a /* lcall */ |
|
||||||
temp_ip: |
|
||||||
.word 0 /* new ip */ |
|
||||||
temp_cs: |
|
||||||
.word 0 /* new cs */ |
|
||||||
|
|
||||||
realmode_ret: |
|
||||||
/* save eax, esp and ss */ |
|
||||||
cs movl %eax, saved_eax |
|
||||||
movl %esp, %eax |
|
||||||
cs movl %eax, saved_esp |
|
||||||
movw %ss, %ax |
|
||||||
cs movw %ax, saved_ss |
|
||||||
|
|
||||||
/* |
|
||||||
* restore the stack, note that we set sp to 0x244;
|
|
||||||
* pt_regs is 0x44 bytes long and we push the structure |
|
||||||
* backwards on to the stack, bottom first |
|
||||||
*/ |
|
||||||
movw $0xc0, %ax |
|
||||||
movw %ax, %ss |
|
||||||
movw $0x244, %ax |
|
||||||
movw %ax, %sp |
|
||||||
|
|
||||||
xorl %eax,%eax |
|
||||||
cs movw saved_ss, %ax |
|
||||||
pushl %eax |
|
||||||
cs movl saved_esp, %eax |
|
||||||
pushl %eax |
|
||||||
o32 pushf |
|
||||||
xorl %eax,%eax |
|
||||||
cs movw temp_cs, %ax |
|
||||||
pushl %eax |
|
||||||
cs movw temp_ip, %ax |
|
||||||
pushl %eax |
|
||||||
pushl $0 |
|
||||||
movw %gs, %ax |
|
||||||
pushl %eax |
|
||||||
movw %fs, %ax |
|
||||||
pushl %eax |
|
||||||
movw %es, %ax |
|
||||||
pushl %eax |
|
||||||
movw %ds, %ax |
|
||||||
pushl %eax |
|
||||||
movl saved_eax, %eax |
|
||||||
pushl %eax |
|
||||||
pushl %ebp |
|
||||||
pushl %edi |
|
||||||
pushl %esi |
|
||||||
pushl %edx |
|
||||||
pushl %ecx |
|
||||||
pushl %ebx |
|
||||||
|
|
||||||
o32 cs lidt saved_idt |
|
||||||
o32 cs lgdt saved_gdt |
|
||||||
|
|
||||||
/* Go back into protected mode reset PE to 1 */ |
|
||||||
movl %cr0, %eax |
|
||||||
orl $1,%eax |
|
||||||
movl %eax, %cr0 |
|
||||||
|
|
||||||
/* flush prefetch queue */ |
|
||||||
jmp next_line |
|
||||||
next_line: |
|
||||||
movw $return_ptr, %ax |
|
||||||
movw %ax,%bp |
|
||||||
o32 cs ljmp *(%bp) |
|
||||||
|
|
||||||
.code32 |
|
||||||
protected_mode: |
|
||||||
/* Reload segment registers */ |
|
||||||
movl $0x18, %eax |
|
||||||
movw %ax, %fs |
|
||||||
movw %ax, %ds |
|
||||||
movw %ax, %gs |
|
||||||
movw %ax, %es |
|
||||||
movw %ax, %ss |
|
||||||
movl saved_protected_mode_esp, %eax |
|
||||||
movl %eax, %esp |
|
||||||
popf |
|
||||||
popa |
|
||||||
ret |
|
||||||
|
|
||||||
temp_eax: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
saved_ss: |
|
||||||
.word 0
|
|
||||||
saved_esp: |
|
||||||
.long 0
|
|
||||||
saved_eax: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
realmode_idt_ptr: |
|
||||||
.word 0x400
|
|
||||||
.word 0x0, 0x0 |
|
||||||
|
|
||||||
saved_gdt: |
|
||||||
.word 0, 0, 0, 0 |
|
||||||
saved_idt: |
|
||||||
.word 0, 0, 0, 0 |
|
||||||
|
|
||||||
saved_protected_mode_esp: |
|
||||||
.long 0
|
|
||||||
|
|
||||||
return_ptr: |
|
||||||
.long protected_mode
|
|
||||||
.word 0x10
|
|
@ -1,196 +0,0 @@ |
|||||||
/*
|
|
||||||
* (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 |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <common.h> |
|
||||||
#include <pci.h> |
|
||||||
#include <malloc.h> |
|
||||||
#include <asm/ptrace.h> |
|
||||||
#include <asm/realmode.h> |
|
||||||
#include <asm/io.h> |
|
||||||
#include <asm/pci.h> |
|
||||||
#include "bios.h" |
|
||||||
|
|
||||||
#undef PCI_BIOS_DEBUG |
|
||||||
#undef VGA_BIOS_DEBUG |
|
||||||
|
|
||||||
#ifdef VGA_BIOS_DEBUG |
|
||||||
#define PRINTF(fmt, args...) printf(fmt, ##args) |
|
||||||
#else |
|
||||||
#define PRINTF(fmt, args...) |
|
||||||
#endif |
|
||||||
|
|
||||||
#define PCI_CLASS_VIDEO 3 |
|
||||||
#define PCI_CLASS_VIDEO_STD 0 |
|
||||||
#define PCI_CLASS_VIDEO_PROG_IF_VGA 0 |
|
||||||
|
|
||||||
DEFINE_PCI_DEVICE_TABLE(supported) = { |
|
||||||
{PCI_VIDEO_VENDOR_ID, PCI_VIDEO_DEVICE_ID}, |
|
||||||
{} |
|
||||||
}; |
|
||||||
|
|
||||||
static u32 probe_pci_video(void) |
|
||||||
{ |
|
||||||
struct pci_controller *hose; |
|
||||||
pci_dev_t devbusfn = pci_find_devices(supported, 0); |
|
||||||
|
|
||||||
if ((devbusfn != -1)) { |
|
||||||
u32 old; |
|
||||||
u32 addr; |
|
||||||
|
|
||||||
/* PCI video device detected */ |
|
||||||
printf("Found PCI VGA device at %02x.%02x.%x\n", |
|
||||||
PCI_BUS(devbusfn), |
|
||||||
PCI_DEV(devbusfn), |
|
||||||
PCI_FUNC(devbusfn)); |
|
||||||
|
|
||||||
/* Enable I/O decoding as well, PCI viudeo boards
|
|
||||||
* support I/O accesses, but they provide no |
|
||||||
* bar register for this since the ports are fixed. |
|
||||||
*/ |
|
||||||
pci_write_config_word(devbusfn, |
|
||||||
PCI_COMMAND, |
|
||||||
PCI_COMMAND_MEMORY | |
|
||||||
PCI_COMMAND_IO | |
|
||||||
PCI_COMMAND_MASTER); |
|
||||||
|
|
||||||
/* Test the ROM decoder, do the device support a rom? */ |
|
||||||
pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &old); |
|
||||||
pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, |
|
||||||
(u32)PCI_ROM_ADDRESS_MASK); |
|
||||||
pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &addr); |
|
||||||
pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, old); |
|
||||||
|
|
||||||
if (!addr) { |
|
||||||
printf("PCI VGA have no ROM?\n"); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
/* device have a rom */ |
|
||||||
if (pci_shadow_rom(devbusfn, (void *)0xc0000)) { |
|
||||||
printf("Shadowing of PCI VGA BIOS failed\n"); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
/* Now enable lagacy VGA port access */ |
|
||||||
hose = pci_bus_to_hose(PCI_BUS(devbusfn)); |
|
||||||
if (pci_enable_legacy_video_ports(hose)) { |
|
||||||
printf("PCI VGA enable failed\n"); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/* return the pci device info, that we'll need later */ |
|
||||||
return PCI_BUS(devbusfn) << 8 | |
|
||||||
PCI_DEV(devbusfn) << 3 | (PCI_FUNC(devbusfn) & 7); |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
static int probe_isa_video(void) |
|
||||||
{ |
|
||||||
u32 ptr; |
|
||||||
char *buf; |
|
||||||
|
|
||||||
ptr = isa_map_rom(0xc0000, 0x8000); |
|
||||||
|
|
||||||
if (!ptr) |
|
||||||
return -1; |
|
||||||
|
|
||||||
buf = malloc(0x8000); |
|
||||||
if (!buf) { |
|
||||||
isa_unmap_rom(ptr); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
if (readw(ptr) != 0xaa55) { |
|
||||||
free(buf); |
|
||||||
isa_unmap_rom(ptr); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
/* shadow the rom */ |
|
||||||
memcpy(buf, (void *)ptr, 0x8000); |
|
||||||
isa_unmap_rom(ptr); |
|
||||||
memcpy((void *)0xc0000, buf, 0x8000); |
|
||||||
|
|
||||||
free(buf); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int video_bios_init(void) |
|
||||||
{ |
|
||||||
struct pt_regs regs; |
|
||||||
int size; |
|
||||||
int i; |
|
||||||
u8 sum; |
|
||||||
|
|
||||||
/* clear the video bios area in case we warmbooted */ |
|
||||||
memset((void *)0xc0000, 0, 0x8000); |
|
||||||
memset(®s, 0, sizeof(struct pt_regs)); |
|
||||||
|
|
||||||
if (probe_isa_video()) |
|
||||||
/* No ISA board found, try the PCI bus */ |
|
||||||
regs.eax = probe_pci_video(); |
|
||||||
|
|
||||||
/* Did we succeed in mapping any video bios */ |
|
||||||
if (readw(0xc0000) == 0xaa55) { |
|
||||||
PRINTF("Found video bios signature\n"); |
|
||||||
size = readb(0xc0002) * 512; |
|
||||||
PRINTF("size %d\n", size); |
|
||||||
sum = 0; |
|
||||||
|
|
||||||
for (i = 0; i < size; i++) |
|
||||||
sum += readb(0xc0000 + i); |
|
||||||
|
|
||||||
PRINTF("Checksum is %sOK\n", sum ? "NOT " : ""); |
|
||||||
|
|
||||||
if (sum) |
|
||||||
return 1; |
|
||||||
|
|
||||||
/*
|
|
||||||
* Some video bioses (ATI Mach64) seem to think that |
|
||||||
* the original int 10 handler is always at |
|
||||||
* 0xf000:0xf065 , place an iret instruction there |
|
||||||
*/ |
|
||||||
writeb(0xcf, 0xff065); |
|
||||||
|
|
||||||
regs.esp = 0x8000; |
|
||||||
regs.xss = 0x2000; |
|
||||||
enter_realmode(0xc000, 3, ®s, ®s); |
|
||||||
|
|
||||||
PRINTF("INT 0x10 vector after: %04x:%04x\n", |
|
||||||
readw(0x42), readw(0x40)); |
|
||||||
PRINTF("BIOS returned %scarry\n", |
|
||||||
regs.eflags & 0x00000001 ? "" : "NOT "); |
|
||||||
#ifdef PCI_BIOS_DEBUG |
|
||||||
print_bios_bios_stat(); |
|
||||||
#endif |
|
||||||
return regs.eflags & 0x00000001; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
return 1; |
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue