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
|
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010,2011 Free Software Foundation, Inc.
*
* GRUB 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 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
FUNCTION(grub_bios_interrupt)
pushf
cli
popf
pushl %ebp
pushl %ecx
pushl %eax
pushl %ebx
pushl %esi
pushl %edi
pushl %edx
movb %al, intno
movl (%edx), %eax
movl %eax, LOCAL(bios_register_eax)
movw 4(%edx), %ax
movw %ax, LOCAL(bios_register_es)
movw 6(%edx), %ax
movw %ax, LOCAL(bios_register_ds)
movw 8(%edx), %ax
movw %ax, LOCAL(bios_register_flags)
movl 12(%edx), %ebx
movl 16(%edx), %ecx
movl 20(%edx), %edi
movl 24(%edx), %esi
movl 28(%edx), %edx
/*
Via C3 CPUs have cache coherence problems, so we need to call
wbinvd at these 2 points. As wbinvd slows down boot, don't do
it on non-VIA. 9090 is nop nop. */
VARIABLE(grub_bios_via_workaround1)
.byte 0x90, 0x90
PROT_TO_REAL
.code16
pushf
cli
mov %ds, %ax
push %ax
/* movw imm16, %ax*/
.byte 0xb8
LOCAL(bios_register_es):
.short 0
movw %ax, %es
/* movw imm16, %ax*/
.byte 0xb8
LOCAL(bios_register_ds):
.short 0
movw %ax, %ds
/* movw imm16, %ax*/
.byte 0xb8
LOCAL(bios_register_flags):
.short 0
push %ax
popf
/* movl imm32, %eax*/
.byte 0x66, 0xb8
LOCAL(bios_register_eax):
.long 0
/* int imm8. */
.byte 0xcd
intno:
.byte 0
movl %eax, %cs:LOCAL(bios_register_eax)
movw %ds, %ax
movw %ax, %cs:LOCAL(bios_register_ds)
pop %ax
mov %ax, %ds
pushf
pop %ax
movw %ax, LOCAL(bios_register_flags)
mov %es, %ax
movw %ax, LOCAL(bios_register_es)
popf
VARIABLE(grub_bios_via_workaround2)
.byte 0x90, 0x90
REAL_TO_PROT
.code32
popl %eax
movl %ebx, 12(%eax)
movl %ecx, 16(%eax)
movl %edi, 20(%eax)
movl %esi, 24(%eax)
movl %edx, 28(%eax)
movl %eax, %edx
movl LOCAL(bios_register_eax), %eax
movl %eax, (%edx)
movw LOCAL(bios_register_es), %ax
movw %ax, 4(%edx)
movw LOCAL(bios_register_ds), %ax
movw %ax, 6(%edx)
movw LOCAL(bios_register_flags), %ax
movw %ax, 8(%edx)
popl %edi
popl %esi
popl %ebx
popl %eax
popl %ecx
popl %ebp
ret
|