138 lines
2.1 KiB
ArmAsm
138 lines
2.1 KiB
ArmAsm
/*
|
|
* Our pretty trivial BIOS emulation
|
|
*/
|
|
|
|
#include "assembly.h"
|
|
#include "processor-flags.h"
|
|
|
|
.org 0
|
|
.code16gcc
|
|
|
|
/*
|
|
* handy BIOS macros
|
|
*/
|
|
|
|
/* If you change these macros, remember to update 'struct biosregs' */
|
|
.macro SAVE_BIOSREGS
|
|
pushl %fs
|
|
pushl %es
|
|
pushl %ds
|
|
pushl %edi
|
|
pushl %esi
|
|
pushl %ebp
|
|
pushl %esp
|
|
pushl %edx
|
|
pushl %ecx
|
|
pushl %ebx
|
|
pushl %eax
|
|
.endm
|
|
|
|
.macro RESTORE_BIOSREGS
|
|
popl %eax
|
|
popl %ebx
|
|
popl %ecx
|
|
popl %edx
|
|
popl %esp
|
|
popl %ebp
|
|
popl %esi
|
|
popl %edi
|
|
popl %ds
|
|
popl %es
|
|
popl %fs
|
|
.endm
|
|
|
|
ENTRY(bios_irq)
|
|
pushw %ax
|
|
mov $0x20, %al
|
|
out %al, $0x20
|
|
popw %ax
|
|
IRET
|
|
ENTRY_END(bios_irq)
|
|
|
|
/*
|
|
* fake interrupt handler, nothing can be faster ever
|
|
*/
|
|
ENTRY(bios_intfake)
|
|
/*
|
|
* Set CF to indicate failure. We don't want callers to think that the
|
|
* interrupt handler succeeded and then treat the return values in
|
|
* registers as valid data.
|
|
*/
|
|
orb $X86_EFLAGS_CF, 0x4(%esp)
|
|
|
|
IRET
|
|
ENTRY_END(bios_intfake)
|
|
|
|
/*
|
|
* int 10 - video - service
|
|
*/
|
|
ENTRY(bios_int10)
|
|
andb $~X86_EFLAGS_CF, 0x4(%esp)
|
|
SAVE_BIOSREGS
|
|
|
|
movl %esp, %eax
|
|
/* this is way easier than doing it in assembly */
|
|
/* just push all the regs and jump to a C handler */
|
|
call int10_handler
|
|
|
|
RESTORE_BIOSREGS
|
|
|
|
IRET
|
|
ENTRY_END(bios_int10)
|
|
|
|
ENTRY(bios_int15)
|
|
andb $~X86_EFLAGS_CF, 0x4(%esp)
|
|
SAVE_BIOSREGS
|
|
|
|
movl %esp, %eax
|
|
call int15_handler
|
|
|
|
RESTORE_BIOSREGS
|
|
|
|
IRET
|
|
ENTRY_END(bios_int15)
|
|
|
|
.code32
|
|
ENTRY(pcibios_entry)
|
|
clc
|
|
pushfl
|
|
SAVE_BIOSREGS
|
|
|
|
movl %esp, %eax
|
|
call pcibios_handler
|
|
|
|
RESTORE_BIOSREGS
|
|
popfl
|
|
lretl
|
|
ENTRY_END(pcibios_entry)
|
|
|
|
ENTRY(bios32_entry)
|
|
pushfl
|
|
testl %ebx, %ebx /* BIOS32 service directory? */
|
|
jnz 2f
|
|
cmp $0x49435024, %eax /* "$PCI"? */
|
|
movb $0x80, %al /* service not present */
|
|
jne 1f
|
|
xorl %ebx, %ebx /* fill in base/length/entry */
|
|
movl $(1 << 20), %ecx
|
|
movl $pcibios_entry, %edx
|
|
movb $0x00, %al /* service present */
|
|
1:
|
|
popfl
|
|
lretl
|
|
2:
|
|
movb $0x81, %al /* unimplemented function */
|
|
popfl
|
|
lretl
|
|
ENTRY_END(bios32_entry)
|
|
|
|
ENTRY(pic_base)
|
|
call 1f
|
|
2:
|
|
ret
|
|
1:
|
|
popl %eax
|
|
pushl %eax
|
|
subl $2b, %eax
|
|
ret /* return to 2b */
|
|
ENTRY_END(pic_base)
|