Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
883da8e2
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
883da8e2
编写于
3月 24, 2004
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
task switch fixes
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@681
c046a42c-6fe2-441c-8c8c-71466251a162
上级
78ebca6e
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
18 addition
and
13 deletion
+18
-13
target-i386/helper.c
target-i386/helper.c
+18
-13
未找到文件。
target-i386/helper.c
浏览文件 @
883da8e2
...
...
@@ -277,7 +277,8 @@ static void tss_load_seg(int seg_reg, int selector)
/* XXX: restore CPU state in registers (PowerPC case) */
static
void
switch_tss
(
int
tss_selector
,
uint32_t
e1
,
uint32_t
e2
,
int
source
)
uint32_t
e1
,
uint32_t
e2
,
int
source
,
uint32_t
next_eip
)
{
int
tss_limit
,
tss_limit_max
,
type
,
old_tss_limit_max
,
old_type
,
v1
,
v2
,
i
;
uint8_t
*
tss_base
;
...
...
@@ -369,7 +370,7 @@ static void switch_tss(int tss_selector,
if
(
source
==
SWITCH_TSS_JMP
||
source
==
SWITCH_TSS_IRET
)
{
uint8_t
*
ptr
;
uint32_t
e2
;
ptr
=
env
->
gdt
.
base
+
(
env
->
tr
.
selector
<<
3
);
ptr
=
env
->
gdt
.
base
+
(
env
->
tr
.
selector
&
~
7
);
e2
=
ldl_kernel
(
ptr
+
4
);
e2
&=
~
DESC_TSS_BUSY_MASK
;
stl_kernel
(
ptr
+
4
,
e2
);
...
...
@@ -381,7 +382,7 @@ static void switch_tss(int tss_selector,
/* save the current state in the old TSS */
if
(
type
&
8
)
{
/* 32 bit */
stl_kernel
(
env
->
tr
.
base
+
0x20
,
env
->
eip
);
stl_kernel
(
env
->
tr
.
base
+
0x20
,
next_
eip
);
stl_kernel
(
env
->
tr
.
base
+
0x24
,
old_eflags
);
for
(
i
=
0
;
i
<
8
;
i
++
)
stl_kernel
(
env
->
tr
.
base
+
(
0x28
+
i
*
4
),
env
->
regs
[
i
]);
...
...
@@ -389,7 +390,7 @@ static void switch_tss(int tss_selector,
stw_kernel
(
env
->
tr
.
base
+
(
0x48
+
i
*
4
),
env
->
segs
[
i
].
selector
);
}
else
{
/* 16 bit */
stw_kernel
(
env
->
tr
.
base
+
0x0e
,
ne
w
_eip
);
stw_kernel
(
env
->
tr
.
base
+
0x0e
,
ne
xt
_eip
);
stw_kernel
(
env
->
tr
.
base
+
0x10
,
old_eflags
);
for
(
i
=
0
;
i
<
8
;
i
++
)
stw_kernel
(
env
->
tr
.
base
+
(
0x12
+
i
*
2
),
env
->
regs
[
i
]);
...
...
@@ -409,7 +410,7 @@ static void switch_tss(int tss_selector,
if
(
source
==
SWITCH_TSS_JMP
||
source
==
SWITCH_TSS_CALL
)
{
uint8_t
*
ptr
;
uint32_t
e2
;
ptr
=
env
->
gdt
.
base
+
(
tss_selector
<<
3
);
ptr
=
env
->
gdt
.
base
+
(
tss_selector
&
~
7
);
e2
=
ldl_kernel
(
ptr
+
4
);
e2
|=
DESC_TSS_BUSY_MASK
;
stl_kernel
(
ptr
+
4
,
e2
);
...
...
@@ -418,6 +419,7 @@ static void switch_tss(int tss_selector,
/* set the new CPU state */
/* from this point, any exception which occurs can give problems */
env
->
cr
[
0
]
|=
CR0_TS_MASK
;
env
->
hflags
|=
HF_TS_MASK
;
env
->
tr
.
selector
=
tss_selector
;
env
->
tr
.
base
=
tss_base
;
env
->
tr
.
limit
=
tss_limit
;
...
...
@@ -486,6 +488,7 @@ static void switch_tss(int tss_selector,
/* check that EIP is in the CS segment limits */
if
(
new_eip
>
env
->
segs
[
R_CS
].
limit
)
{
/* XXX: different exception if CALL ? */
raise_exception_err
(
EXCP0D_GPF
,
0
);
}
}
...
...
@@ -603,6 +606,10 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
break
;
}
}
if
(
is_int
)
old_eip
=
next_eip
;
else
old_eip
=
env
->
eip
;
dt
=
&
env
->
idt
;
if
(
intno
*
8
+
7
>
dt
->
limit
)
...
...
@@ -617,7 +624,7 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
/* must do that check here to return the correct error code */
if
(
!
(
e2
&
DESC_P_MASK
))
raise_exception_err
(
EXCP0B_NOSEG
,
intno
*
8
+
2
);
switch_tss
(
intno
*
8
,
e1
,
e2
,
SWITCH_TSS_CALL
);
switch_tss
(
intno
*
8
,
e1
,
e2
,
SWITCH_TSS_CALL
,
old_eip
);
if
(
has_error_code
)
{
int
mask
;
/* push the error code */
...
...
@@ -713,10 +720,6 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
push_size += 8;
push_size <<= shift;
#endif
if
(
is_int
)
old_eip
=
next_eip
;
else
old_eip
=
env
->
eip
;
if
(
shift
==
1
)
{
if
(
new_stack
)
{
if
(
env
->
eflags
&
VM_MASK
)
{
...
...
@@ -1264,7 +1267,8 @@ void helper_ljmp_protected_T0_T1(void)
case
5
:
/* task gate */
if
(
dpl
<
cpl
||
dpl
<
rpl
)
raise_exception_err
(
EXCP0D_GPF
,
new_cs
&
0xfffc
);
switch_tss
(
new_cs
,
e1
,
e2
,
SWITCH_TSS_JMP
);
/* XXX: check if it is really the current EIP */
switch_tss
(
new_cs
,
e1
,
e2
,
SWITCH_TSS_JMP
,
env
->
eip
);
break
;
case
4
:
/* 286 call gate */
case
12
:
/* 386 call gate */
...
...
@@ -1405,7 +1409,7 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
case
5
:
/* task gate */
if
(
dpl
<
cpl
||
dpl
<
rpl
)
raise_exception_err
(
EXCP0D_GPF
,
new_cs
&
0xfffc
);
switch_tss
(
new_cs
,
e1
,
e2
,
SWITCH_TSS_CALL
);
switch_tss
(
new_cs
,
e1
,
e2
,
SWITCH_TSS_CALL
,
next_eip
);
return
;
case
4
:
/* 286 call gate */
case
12
:
/* 386 call gate */
...
...
@@ -1744,7 +1748,8 @@ void helper_iret_protected(int shift)
/* NOTE: we check both segment and busy TSS */
if
(
type
!=
3
)
raise_exception_err
(
EXCP0A_TSS
,
tss_selector
&
0xfffc
);
switch_tss
(
tss_selector
,
e1
,
e2
,
SWITCH_TSS_IRET
);
/* XXX: check if it is really the current EIP */
switch_tss
(
tss_selector
,
e1
,
e2
,
SWITCH_TSS_IRET
,
env
->
eip
);
}
else
{
helper_ret_protected
(
shift
,
1
,
0
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录