3 Copyright (C) 2007-2009 Jörg Pfähler
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <kernel/log.hpp>
21 #include <kernel/x86/v86m.hpp>
22 #include <kernel/processor.hpp>
24 using namespace kernel
;
27 void kernel::push16(uint32_t **Esp
, uint16_t value
)
29 uint16_t *stack
= reinterpret_cast<uint16_t*>(*Esp
);
31 *Esp
= reinterpret_cast<uint32_t*>(stack
);
33 uint16_t kernel::pop16(uint32_t **Esp
)
35 uint16_t *stack
= reinterpret_cast<uint16_t*>(*Esp
);
36 uint16_t result
= *stack
;
37 *Esp
= reinterpret_cast<uint32_t*>(stack
);
40 void kernel::virtual_8086_monitor(interrupt_stackframe
&frame
)
42 uint8_t *Eip
= reinterpret_cast<uint8_t*>((frame
.cs
<< 4) + frame
.eip
);
43 uint32_t *Esp
= reinterpret_cast<uint32_t*>((frame
.ss
<< 4) + frame
.esp
);
44 uint16_t *Ivt
= reinterpret_cast<uint16_t*>(0);
51 uint8_t Number
= *Eip
++;
53 // Stack large enough?
56 FATAL("virtual-8086-monitor: Int n: Stack not large enough\n");
57 FATAL("Halting System" << endl
);
63 asm volatile("int $0xEF");
67 push16(&Esp
, frame
.eflags
& 0xFFFF);
69 push16(&Esp
, frame
.cs
);
71 push16(&Esp
, reinterpret_cast<uintptr_t>(Eip
));
73 // Get new CS:EIP from IVT
74 frame
.cs
= *(Ivt
+ 2 * Number
+ 1);
75 frame
.eip
= *(Ivt
+ 2 * Number
);
79 // Stack large enough?
80 if (frame
.esp
> 0xFFFA)
82 FATAL("virtual-8086-monitor: IRET: Stack not large enough\n");
83 FATAL("Halting System" << endl
);
88 frame
.eip
= pop16(&Esp
);
90 frame
.cs
= pop16(&Esp
);
92 frame
.eflags
= (frame
.eflags
& 0xFFFF0000) | pop16(&Esp
) | 0x3202;
96 FATAL("virtual-8086-monitor: Unknown instruction 0x" << hex
<< *Eip
<< '\n');
97 FATAL("Halting System" << endl
);
103 frame
.esp
= reinterpret_cast<uintptr_t>(Esp
) - (frame
.ss
<< 4);