1/* 2 * FreeLoader 3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 .text 21 .code16 22 23#define ASM 24#include <arch.h> 25 26/* Only these flags are propagated into Int386() */ 27#define FLAGS_PROP (I386FLAG_CF | \ 28 I386FLAG_ZF | \ 29 I386FLAG_SF) 30 31Int386_REGS: 32 33Int386_eax: 34 .long 0 35Int386_ebx: 36 .long 0 37Int386_ecx: 38 .long 0 39Int386_edx: 40 .long 0 41 42Int386_esi: 43 .long 0 44Int386_edi: 45 .long 0 46 47Int386_ds: 48 .word 0 49Int386_es: 50 .word 0 51Int386_fs: 52 .word 0 53Int386_gs: 54 .word 0 55 56Int386_eflags: 57 .long 0 58 59Int386_vector: 60 .long 0 61Int386_regsin: 62 .long 0 63Int386_regsout: 64 .long 0 65 66/* 67 * int Int386(int ivec, REGS* in, REGS* out); 68 */ 69EXTERN(_Int386) 70 .code32 71 72 /* Get the function parameters */ 73 movl 0x04(%esp),%eax 74 movl %eax,Int386_vector 75 movb %al,Int386_vector_opcode 76 movl 0x08(%esp),%eax 77 movl %eax,Int386_regsin 78 movl 0x0c(%esp),%eax 79 movl %eax,Int386_regsout 80 81 /* Save all registers + segment registers */ 82 pushw %ds 83 pushw %es 84 pushw %fs 85 pushw %gs 86 pushal 87 88 /* Copy the input regs to our variables */ 89 movl $Int386_REGS,%edi 90 movl Int386_regsin,%esi 91 movl $0x24,%ecx 92 cld 93 rep 94 movsb 95 96 call switch_to_real 97 .code16 98 99 /* Setup the registers */ 100 movw %cs:Int386_ds,%ax 101 movw %ax,%ds /* DS register */ 102 movw %cs:Int386_es,%ax 103 movw %ax,%es /* ES register */ 104 movw %cs:Int386_fs,%ax 105 movw %ax,%fs /* FS register */ 106 movw %cs:Int386_gs,%ax 107 movw %ax,%gs /* GS register */ 108 109 /* Prepare EFLAGS for recover */ 110 pushf 111 movw %cs:Int386_eflags, %ax 112 popw %cx 113 andw $FLAGS_PROP, %ax 114 andw $~FLAGS_PROP, %cx 115 orw %cx, %ax 116 pushw %ax 117 118 /* Recover general purpose registers */ 119 movl %cs:Int386_eax,%eax /* EAX register */ 120 movl %cs:Int386_ebx,%ebx /* EBX register */ 121 movl %cs:Int386_ecx,%ecx /* ECX register */ 122 movl %cs:Int386_edx,%edx /* EDX register */ 123 124 movl %cs:Int386_esi,%esi /* ESI register */ 125 movl %cs:Int386_edi,%edi /* EDI register */ 126 127 /* Recover previously prepared flags */ 128 popf 129 130 /* Do not set the flags register */ 131 /* only return its value in regsout */ 132 //pushl Int386_eflags 133 //popfl /* EFLAGS register */ 134 135 /* Call the interrupt vector */ 136 /*int Int386_vector*/ 137Int386_int_opcode: 138 .byte 0xcd 139Int386_vector_opcode: 140 .byte 0x00 141 142 /* Save the registers */ 143 movl %eax,%cs:Int386_eax /* EAX register */ 144 movl %ebx,%cs:Int386_ebx /* EBX register */ 145 movl %ecx,%cs:Int386_ecx /* ECX register */ 146 movl %edx,%cs:Int386_edx /* EDX register */ 147 148 movl %esi,%cs:Int386_esi /* ESI register */ 149 movl %edi,%cs:Int386_edi /* EDI register */ 150 151 movw %ds,%ax /* DS register */ 152 movw %ax,%cs:Int386_ds 153 movw %es,%ax /* ES register */ 154 movw %ax,%cs:Int386_es 155 movw %fs,%ax /* FS register */ 156 movw %ax,%cs:Int386_fs 157 movw %gs,%ax /* GS register */ 158 movw %ax,%cs:Int386_gs 159 160 pushf 161 popw %cs:Int386_eflags /* EFLAGS register */ 162 163 call switch_to_prot 164 .code32 165 166 /* Copy the variables to the output regs */ 167 movl $Int386_REGS,%esi 168 movl Int386_regsout,%edi 169 movl $0x24,%ecx 170 cld 171 rep 172 movsb 173 174 /* Restore segment and all other registers */ 175 176 177 popal 178 popw %gs 179 popw %fs 180 popw %es 181 popw %ds 182 183 /* Get return value */ 184 movl Int386_eax,%eax 185 186 ret 187