1 /////////////////////////////////////////////////////////////////////////
2 // $Id: soft_int.cc,v 1.45 2008/10/01 09:44:40 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
31 #define LOG_THIS BX_CPU_THIS_PTR
33 // Make code more tidy with a few macros.
34 #if BX_SUPPORT_X86_64==0
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::BOUND_GwMa(bxInstruction_c
*i
)
40 Bit16s bound_min
, bound_max
;
41 Bit16s op1_16
= BX_READ_16BIT_REG(i
->nnn());
43 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
45 bound_min
= (Bit16s
) read_virtual_word(i
->seg(), eaddr
);
46 bound_max
= (Bit16s
) read_virtual_word(i
->seg(), eaddr
+2);
48 if (op1_16
< bound_min
|| op1_16
> bound_max
) {
49 BX_INFO(("BOUND_GdMa: fails bounds test"));
50 exception(BX_BR_EXCEPTION
, 0, 0);
54 void BX_CPP_AttrRegparmN(1) BX_CPU_C::BOUND_GdMa(bxInstruction_c
*i
)
56 Bit32s bound_min
, bound_max
;
57 Bit32s op1_32
= BX_READ_32BIT_REG(i
->nnn());
59 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
61 bound_min
= (Bit32s
) read_virtual_dword(i
->seg(), eaddr
);
62 bound_max
= (Bit32s
) read_virtual_dword(i
->seg(), eaddr
+4);
64 if (op1_32
< bound_min
|| op1_32
> bound_max
) {
65 BX_INFO(("BOUND_GdMa: fails bounds test"));
66 exception(BX_BR_EXCEPTION
, 0, 0);
70 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INT1(bxInstruction_c
*i
)
72 // This is an undocumented instrucion (opcode 0xf1)
73 // which is useful for an ICE system.
76 BX_CPU_THIS_PTR show_flag
|= Flag_softint
;
79 BX_CPU_THIS_PTR speculative_rsp
= 1;
80 BX_CPU_THIS_PTR prev_rsp
= RSP
;
82 // interrupt is not RSP safe
83 interrupt(1, 1, 0, 0);
85 BX_CPU_THIS_PTR speculative_rsp
= 0;
87 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_INT
,
88 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
,
92 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INT3(bxInstruction_c
*i
)
94 // INT 3 is not IOPL sensitive
97 BX_CPU_THIS_PTR show_flag
|= Flag_softint
;
100 BX_CPU_THIS_PTR speculative_rsp
= 1;
101 BX_CPU_THIS_PTR prev_rsp
= RSP
;
103 // interrupt is not RSP safe
104 interrupt(3, 1, 0, 0);
106 BX_CPU_THIS_PTR speculative_rsp
= 0;
108 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_INT
,
109 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
,
114 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INT_Ib(bxInstruction_c
*i
)
117 BX_CPU_THIS_PTR show_flag
|= Flag_softint
;
120 Bit8u vector
= i
->Ib();
122 BX_CPU_THIS_PTR speculative_rsp
= 1;
123 BX_CPU_THIS_PTR prev_rsp
= RSP
;
127 if (BX_CPU_THIS_PTR cr4
.get_VME())
129 bx_address tr_base
= BX_CPU_THIS_PTR tr
.cache
.u
.system
.base
;
131 Bit16u io_base
= system_read_word(tr_base
+ 102);
132 Bit8u vme_redirection_bitmap
= system_read_byte(tr_base
+ io_base
- 32 + (vector
>> 3));
134 if (! (vme_redirection_bitmap
& (1 << (vector
& 7))))
136 // redirect interrupt through virtual-mode idt
137 v86_redirect_interrupt(vector
);
142 // interrupt is not redirected or VME is OFF
143 if (BX_CPU_THIS_PTR
get_IOPL() < 3)
145 BX_DEBUG(("INT_Ib(): Interrupt cannot be redirected, generate #GP(0)"));
146 exception(BX_GP_EXCEPTION
, 0, 0);
150 #ifdef SHOW_EXIT_STATUS
151 if ((vector
== 0x21) && (AH
== 0x4c)) {
152 BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x", (unsigned) AL
, (unsigned) BX
));
156 interrupt(vector
, 1, 0, 0);
160 BX_CPU_THIS_PTR speculative_rsp
= 0;
162 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_INT
,
163 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
,
167 void BX_CPP_AttrRegparmN(1) BX_CPU_C::INTO(bxInstruction_c
*i
)
170 BX_CPU_THIS_PTR show_flag
|= Flag_softint
;
174 BX_CPU_THIS_PTR speculative_rsp
= 1;
175 BX_CPU_THIS_PTR prev_rsp
= RSP
;
177 // interrupt is not RSP safe
178 interrupt(4, 1, 0, 0);
180 BX_CPU_THIS_PTR speculative_rsp
= 0;
182 BX_INSTR_FAR_BRANCH(BX_CPU_ID
, BX_INSTR_IS_INT
,
183 BX_CPU_THIS_PTR sregs
[BX_SEG_REG_CS
].selector
.value
,