Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
15f746ce
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看板
未验证
提交
15f746ce
编写于
2月 09, 2016
作者:
A
Artyom Tarasenko
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
target-sparc: implement UA2005 TSB Pointers
Signed-off-by:
N
Artyom Tarasenko
<
atar4qemu@gmail.com
>
上级
96df2bc9
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
104 addition
and
22 deletion
+104
-22
target/sparc/cpu.h
target/sparc/cpu.h
+2
-0
target/sparc/ldst_helper.c
target/sparc/ldst_helper.c
+102
-22
未找到文件。
target/sparc/cpu.h
浏览文件 @
15f746ce
...
...
@@ -417,6 +417,8 @@ typedef union {
uint64_t
tag_access
;
uint64_t
virtual_watchpoint
;
uint64_t
physical_watchpoint
;
uint64_t
sun4v_ctx_config
[
2
];
uint64_t
sun4v_tsb_pointers
[
4
];
};
}
SparcV9MMU
;
#endif
...
...
target/sparc/ldst_helper.c
浏览文件 @
15f746ce
...
...
@@ -70,11 +70,29 @@
#define QT1 (env->qt1)
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
/* Calculates TSB pointer value for fault page size 8k or 64k */
static
uint64_t
ultrasparc_tsb_pointer
(
uint64_t
tsb_registe
r
,
static
uint64_t
ultrasparc_tsb_pointer
(
CPUSPARCState
*
env
,
uint64_t
tsb
,
uint64_t
*
tsb_pt
r
,
uint64_t
tag_access_register
,
int
page_size
)
int
idx
,
uint64_t
*
cfg_ptr
)
/* Calculates TSB pointer value for fault page size
* UltraSPARC IIi has fixed sizes (8k or 64k) for the page pointers
* UA2005 holds the page size configuration in mmu_ctx registers */
{
uint64_t
tsb_register
;
int
page_size
;
if
(
cpu_has_hypervisor
(
env
))
{
int
tsb_index
=
0
;
int
ctx
=
tag_access_register
&
0x1fffULL
;
uint64_t
ctx_register
=
cfg_ptr
[
ctx
?
1
:
0
];
tsb_index
=
idx
;
tsb_index
|=
ctx
?
2
:
0
;
page_size
=
idx
?
ctx_register
>>
8
:
ctx_register
;
page_size
&=
7
;
tsb_register
=
tsb_ptr
[
tsb_index
];
}
else
{
page_size
=
idx
;
tsb_register
=
tsb
;
}
uint64_t
tsb_base
=
tsb_register
&
~
0x1fffULL
;
int
tsb_split
=
(
tsb_register
&
0x1000ULL
)
?
1
:
0
;
int
tsb_size
=
tsb_register
&
0xf
;
...
...
@@ -87,21 +105,15 @@ static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
uint64_t
va
=
tag_access_va
;
/* move va bits to correct position */
if
(
page_size
==
8
*
1024
)
{
va
>>=
9
;
}
else
if
(
page_size
==
64
*
1024
)
{
va
>>=
12
;
}
va
>>=
3
*
page_size
+
9
;
if
(
tsb_size
)
{
tsb_base_mask
<<=
tsb_size
;
}
tsb_base_mask
<<=
tsb_size
;
/* calculate tsb_base mask and adjust va if split is in use */
if
(
tsb_split
)
{
if
(
page_size
==
8
*
1024
)
{
if
(
idx
==
0
)
{
va
&=
~
(
1ULL
<<
(
13
+
tsb_size
));
}
else
if
(
page_size
==
64
*
1024
)
{
}
else
{
va
|=
(
1ULL
<<
(
13
+
tsb_size
));
}
tsb_base_mask
<<=
1
;
...
...
@@ -1256,16 +1268,20 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
{
/* env->immuregs[5] holds I-MMU TSB register value
env->immuregs[6] holds I-MMU Tag Access register value */
ret
=
ultrasparc_tsb_pointer
(
env
->
immu
.
tsb
,
env
->
immu
.
tag_access
,
8
*
1024
);
ret
=
ultrasparc_tsb_pointer
(
env
,
env
->
immu
.
tsb
,
env
->
immu
.
sun4v_tsb_pointers
,
env
->
immu
.
tag_access
,
0
,
env
->
immu
.
sun4v_ctx_config
);
break
;
}
case
ASI_IMMU_TSB_64KB_PTR
:
/* I-MMU 64k TSB pointer */
{
/* env->immuregs[5] holds I-MMU TSB register value
env->immuregs[6] holds I-MMU Tag Access register value */
ret
=
ultrasparc_tsb_pointer
(
env
->
immu
.
tsb
,
env
->
immu
.
tag_access
,
64
*
1024
);
ret
=
ultrasparc_tsb_pointer
(
env
,
env
->
immu
.
tsb
,
env
->
immu
.
sun4v_tsb_pointers
,
env
->
immu
.
tag_access
,
1
,
env
->
immu
.
sun4v_ctx_config
);
break
;
}
case
ASI_ITLB_DATA_ACCESS
:
/* I-MMU data access */
...
...
@@ -1324,16 +1340,20 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
{
/* env->dmmuregs[5] holds D-MMU TSB register value
env->dmmuregs[6] holds D-MMU Tag Access register value */
ret
=
ultrasparc_tsb_pointer
(
env
->
dmmu
.
tsb
,
env
->
dmmu
.
tag_access
,
8
*
1024
);
ret
=
ultrasparc_tsb_pointer
(
env
,
env
->
dmmu
.
tsb
,
env
->
dmmu
.
sun4v_tsb_pointers
,
env
->
dmmu
.
tag_access
,
0
,
env
->
dmmu
.
sun4v_ctx_config
);
break
;
}
case
ASI_DMMU_TSB_64KB_PTR
:
/* D-MMU 64k TSB pointer */
{
/* env->dmmuregs[5] holds D-MMU TSB register value
env->dmmuregs[6] holds D-MMU Tag Access register value */
ret
=
ultrasparc_tsb_pointer
(
env
->
dmmu
.
tsb
,
env
->
dmmu
.
tag_access
,
64
*
1024
);
ret
=
ultrasparc_tsb_pointer
(
env
,
env
->
dmmu
.
tsb
,
env
->
dmmu
.
sun4v_tsb_pointers
,
env
->
dmmu
.
tag_access
,
1
,
env
->
dmmu
.
sun4v_ctx_config
);
break
;
}
case
ASI_DTLB_DATA_ACCESS
:
/* D-MMU data access */
...
...
@@ -1471,7 +1491,67 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
case
ASI_TWINX_SL
:
/* Secondary, twinx, LE */
/* These are always handled inline. */
g_assert_not_reached
();
/* these ASIs have different functions on UltraSPARC-IIIi
* and UA2005 CPUs. Use the explicit numbers to avoid confusion
*/
case
0x31
:
case
0x32
:
case
0x39
:
case
0x3a
:
if
(
cpu_has_hypervisor
(
env
))
{
/* UA2005
* ASI_DMMU_CTX_ZERO_TSB_BASE_PS0
* ASI_DMMU_CTX_ZERO_TSB_BASE_PS1
* ASI_DMMU_CTX_NONZERO_TSB_BASE_PS0
* ASI_DMMU_CTX_NONZERO_TSB_BASE_PS1
*/
int
idx
=
((
asi
&
2
)
>>
1
)
|
((
asi
&
8
)
>>
2
);
env
->
dmmu
.
sun4v_tsb_pointers
[
idx
]
=
val
;
}
else
{
helper_raise_exception
(
env
,
TT_ILL_INSN
);
}
break
;
case
0x33
:
case
0x3b
:
if
(
cpu_has_hypervisor
(
env
))
{
/* UA2005
* ASI_DMMU_CTX_ZERO_CONFIG
* ASI_DMMU_CTX_NONZERO_CONFIG
*/
env
->
dmmu
.
sun4v_ctx_config
[(
asi
&
8
)
>>
3
]
=
val
;
}
else
{
helper_raise_exception
(
env
,
TT_ILL_INSN
);
}
break
;
case
0x35
:
case
0x36
:
case
0x3d
:
case
0x3e
:
if
(
cpu_has_hypervisor
(
env
))
{
/* UA2005
* ASI_IMMU_CTX_ZERO_TSB_BASE_PS0
* ASI_IMMU_CTX_ZERO_TSB_BASE_PS1
* ASI_IMMU_CTX_NONZERO_TSB_BASE_PS0
* ASI_IMMU_CTX_NONZERO_TSB_BASE_PS1
*/
int
idx
=
((
asi
&
2
)
>>
1
)
|
((
asi
&
8
)
>>
2
);
env
->
immu
.
sun4v_tsb_pointers
[
idx
]
=
val
;
}
else
{
helper_raise_exception
(
env
,
TT_ILL_INSN
);
}
break
;
case
0x37
:
case
0x3f
:
if
(
cpu_has_hypervisor
(
env
))
{
/* UA2005
* ASI_IMMU_CTX_ZERO_CONFIG
* ASI_IMMU_CTX_NONZERO_CONFIG
*/
env
->
immu
.
sun4v_ctx_config
[(
asi
&
8
)
>>
3
]
=
val
;
}
else
{
helper_raise_exception
(
env
,
TT_ILL_INSN
);
}
break
;
case
ASI_UPA_CONFIG
:
/* UPA config */
/* XXX */
return
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录