aboutsummaryrefslogtreecommitdiff
path: root/vgasrc/vgaentry.S
blob: 5d4538088f69beb4a880efd3a2e35c299d236f96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Rom layout and bios assembler to C interface.
//
// Copyright (C) 2009-2013  Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.


#include "asm-offsets.h" // BREGS_*
#include "config.h" // CONFIG_*
#include "entryfuncs.S" // ENTRY_*


/****************************************************************
 * Rom Header
 ****************************************************************/

        .section .rom.header
        .code16
        .global _rom_header, _rom_header_size, _rom_header_checksum
_rom_header:
        .word 0xaa55
_rom_header_size:
        .byte 0
_rom_header_entry:
        jmp _optionrom_entry
_rom_header_checksum:
        .byte 0
_rom_header_other:
        .space 17
_rom_header_pcidata:
#if CONFIG_VGA_PCI == 1
        .word rom_pci_data
#else
        .word 0
#endif
_rom_header_pnpdata:
        .word 0
_rom_header_other2:
        .word 0
_rom_header_signature:
        .asciz "IBM"


/****************************************************************
 * Entry points
 ****************************************************************/

        // Force a fault if found to be running on broken x86emu versions.
        DECLFUNC x86emu_fault
msg:    .ascii "SeaVGABIOS: x86emu leal trap!\n"
x86emu_fault:
#if CONFIG_DEBUG_IO
        movw %cs:DebugOutputPort, %dx
        movw $msg, %si
1:      movb %cs:(%si), %al
        outb %al, (%dx)
        incw %si
        cmpw $x86emu_fault, %si
        jl 1b
#endif
1:      hlt
        jmp 1b

        // This macro implements a call while avoiding instructions
        // that old versions of x86emu have problems with.
        .macro VGA_CALLL cfunc
        // Make sure leal instruction works.
        movl $0x8000, %ecx
        leal (%ecx, %ecx, 1), %ecx
        cmpl $0x10000, %ecx
        jne x86emu_fault
        // Use callw instead of calll
        push %ax
        callw \cfunc
        .endm

        // This macro is the same as ENTRY_ARG except VGA_CALLL is used.
        .macro ENTRY_ARG_VGA cfunc
        cli
        cld
        PUSHBREGS
        movw %ss, %ax           // Move %ss to %ds
        movw %ax, %ds
        movl %esp, %ebx         // Backup %esp, then zero high bits
        movzwl %sp, %esp
        movl %esp, %eax         // First arg is pointer to struct bregs
        VGA_CALLL \cfunc
        movl %ebx, %esp         // Restore %esp (including high bits)
        POPBREGS
        .endm

        DECLFUNC entry_104f05
entry_104f05:
        ENTRY_ARG_VGA vbe_104f05
        lretw

        DECLFUNC _optionrom_entry
_optionrom_entry:
        ENTRY_ARG_VGA vga_post
        lretw

        DECLFUNC entry_10
entry_10:
        ENTRY_ARG_VGA handle_10
        iretw

        // Entry point using extra stack
        DECLFUNC entry_10_extrastack
entry_10_extrastack:
        cli
        cld
        pushw %ds               // Set %ds:%eax to space on ExtraStack
        pushl %eax
        movw %cs:ExtraStackSeg, %ds
        movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
        SAVEBREGS_POP_DSEAX     // Save registers on extra stack
        movl %esp, BREGS_size+0(%eax)
        movw %ss, BREGS_size+4(%eax)
        popl BREGS_code(%eax)
        popw BREGS_flags(%eax)

        movw %ds, %dx           // Setup %ss/%esp and call function
        movw %dx, %ss
        movl %eax, %esp
        VGA_CALLL handle_10

        movl %esp, %eax         // Restore registers and return
        movw BREGS_size+4(%eax), %ss
        movl BREGS_size+0(%eax), %esp
        popl %edx
        popw %dx
        pushw BREGS_flags(%eax)
        pushl BREGS_code(%eax)
        RESTOREBREGS_DSEAX
        iretw