diff options
Diffstat (limited to 'roms/qboot/entry.S')
-rw-r--r-- | roms/qboot/entry.S | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/roms/qboot/entry.S b/roms/qboot/entry.S new file mode 100644 index 000000000..31d840bac --- /dev/null +++ b/roms/qboot/entry.S @@ -0,0 +1,138 @@ +/* + * 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) |