Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
4b3686fa
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看板
提交
4b3686fa
编写于
5月 23, 2004
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
PowerPC merge
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@861
c046a42c-6fe2-441c-8c8c-71466251a162
上级
85c4adf6
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
274 addition
and
150 deletion
+274
-150
target-ppc/exec.h
target-ppc/exec.h
+6
-0
target-ppc/helper.c
target-ppc/helper.c
+13
-14
target-ppc/op.c
target-ppc/op.c
+16
-18
target-ppc/op_helper.c
target-ppc/op_helper.c
+95
-10
target-ppc/op_template.h
target-ppc/op_template.h
+1
-4
target-ppc/translate.c
target-ppc/translate.c
+143
-104
未找到文件。
target-ppc/exec.h
浏览文件 @
4b3686fa
...
...
@@ -135,6 +135,8 @@ void do_sraw(void);
void
do_fctiw
(
void
);
void
do_fctiwz
(
void
);
void
do_fnmadd
(
void
);
void
do_fnmsub
(
void
);
void
do_fnmadds
(
void
);
void
do_fnmsubs
(
void
);
void
do_fsqrt
(
void
);
...
...
@@ -147,7 +149,11 @@ void do_fcmpo (void);
void
do_fabs
(
void
);
void
do_fnabs
(
void
);
void
do_check_reservation
(
void
);
void
do_icbi
(
void
);
void
do_store_sr
(
uint32_t
srnum
);
void
do_store_ibat
(
int
ul
,
int
nr
);
void
do_store_dbat
(
int
ul
,
int
nr
);
void
do_tlbia
(
void
);
void
do_tlbie
(
void
);
...
...
target-ppc/helper.c
浏览文件 @
4b3686fa
...
...
@@ -28,9 +28,6 @@
//#define DEBUG_EXCEPTIONS
extern
FILE
*
stdout
,
*
stderr
;
void
abort
(
void
);
/*****************************************************************************/
/*****************************************************************************/
/* PPC MMU emulation */
...
...
@@ -365,7 +362,8 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
fprintf
(
logfile
,
"%s
\n
"
,
__func__
);
}
if
((
access_type
==
ACCESS_CODE
&&
msr_ir
==
0
)
||
msr_dr
==
0
)
{
if
((
access_type
==
ACCESS_CODE
&&
msr_ir
==
0
)
||
(
access_type
!=
ACCESS_CODE
&&
msr_dr
==
0
))
{
/* No address translation */
*
physical
=
address
&
~
0xFFF
;
*
prot
=
PAGE_READ
|
PAGE_WRITE
;
...
...
@@ -441,12 +439,15 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr)
index
=
(
addr
>>
TARGET_PAGE_BITS
)
&
(
CPU_TLB_SIZE
-
1
);
tlb_addrr
=
env
->
tlb_read
[
is_user
][
index
].
address
;
tlb_addrw
=
env
->
tlb_write
[
is_user
][
index
].
address
;
#if 0
printf("%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx "
#if 1
if
(
loglevel
)
{
fprintf
(
logfile
,
"%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx "
"(0x%08lx 0x%08lx)
\n
"
,
__func__
,
env
,
&
env
->
tlb_read
[
is_user
][
index
],
index
,
addr
,
tlb_addrr
,
tlb_addrw
,
addr
&
TARGET_PAGE_MASK
,
tlb_addrr
&
(
TARGET_PAGE_MASK
|
TLB_INVALID_MASK
));
}
#endif
}
ret
=
cpu_ppc_handle_mmu_fault
(
env
,
addr
,
is_write
,
is_user
,
1
);
...
...
@@ -631,11 +632,14 @@ uint32_t _load_msr (CPUState *env)
void
_store_msr
(
CPUState
*
env
,
uint32_t
value
)
{
#if 0 // TRY
if (((value >> MSR_IR) & 0x01) != msr_ir ||
((
value
>>
MSR_DR
)
&
0x01
)
!=
msr_dr
)
{
((value >> MSR_DR) & 0x01) != msr_dr)
{
/* Flush all tlb when changing translation mode or privilege level */
tlb_flush(env, 1);
}
#endif
msr_pow
=
(
value
>>
MSR_POW
)
&
0x03
;
msr_ile
=
(
value
>>
MSR_ILE
)
&
0x01
;
msr_ee
=
(
value
>>
MSR_EE
)
&
0x01
;
...
...
@@ -699,13 +703,8 @@ void do_interrupt (CPUState *env)
goto
store_next
;
case
EXCP_MACHINE_CHECK
:
if
(
msr_me
==
0
)
{
printf
(
"Machine check exception while not allowed !
\n
"
);
if
(
loglevel
)
{
fprintf
(
logfile
,
"Machine check exception while not allowed !
\n
"
);
cpu_abort
(
env
,
"Machine check exception while not allowed
\n
"
);
}
abort
();
}
msr_me
=
0
;
break
;
case
EXCP_DSI
:
...
...
@@ -801,7 +800,7 @@ void do_interrupt (CPUState *env)
env
->
fpscr
[
7
]
|=
0x4
;
break
;
case
EXCP_INVAL
:
printf
(
"Invalid instruction at 0x%08x
\n
"
,
env
->
nip
);
//
printf("Invalid instruction at 0x%08x\n", env->nip);
msr
|=
0x00080000
;
break
;
case
EXCP_PRIV
:
...
...
target-ppc/op.c
浏览文件 @
4b3686fa
...
...
@@ -242,10 +242,7 @@ PPC_OP(load_srin)
PPC_OP
(
store_srin
)
{
#if defined (DEBUG_OP)
dump_store_sr
(
T1
>>
28
);
#endif
regs
->
sr
[
T1
>>
28
]
=
T0
;
do_store_sr
(
T1
>>
28
);
RETURN
();
}
...
...
@@ -402,10 +399,7 @@ PPC_OP(load_ibat)
PPC_OP
(
store_ibat
)
{
#if defined (DEBUG_OP)
dump_store_ibat
(
PARAM
(
1
),
PARAM
(
2
));
#endif
regs
->
IBAT
[
PARAM
(
1
)][
PARAM
(
2
)]
=
T0
;
do_store_ibat
(
PARAM
(
1
),
PARAM
(
2
));
}
PPC_OP
(
load_dbat
)
...
...
@@ -415,10 +409,7 @@ PPC_OP(load_dbat)
PPC_OP
(
store_dbat
)
{
#if defined (DEBUG_OP)
dump_store_dbat
(
PARAM
(
1
),
PARAM
(
2
));
#endif
regs
->
DBAT
[
PARAM
(
1
)][
PARAM
(
2
)]
=
T0
;
do_store_dbat
(
PARAM
(
1
),
PARAM
(
2
));
}
/* FPSCR */
...
...
@@ -1344,9 +1335,7 @@ PPC_OP(fmsubs)
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
PPC_OP
(
fnmadd
)
{
FT0
*=
FT1
;
FT0
+=
FT2
;
FT0
=
-
FT0
;
do_fnmadd
();
RETURN
();
}
...
...
@@ -1360,9 +1349,7 @@ PPC_OP(fnmadds)
/* fnmsub - fnmsub. */
PPC_OP
(
fnmsub
)
{
FT0
*=
FT1
;
FT0
-=
FT2
;
FT0
=
-
FT0
;
do_fnmsub
();
RETURN
();
}
...
...
@@ -1444,11 +1431,22 @@ PPC_OP(fneg)
#include "op_mem.h"
#endif
/* Special op to check and maybe clear reservation */
PPC_OP
(
check_reservation
)
{
do_check_reservation
();
RETURN
();
}
/* Return from interrupt */
PPC_OP
(
rfi
)
{
regs
->
nip
=
regs
->
spr
[
SRR0
]
&
~
0x00000003
;
#if 1 // TRY
T0
=
regs
->
spr
[
SRR1
]
&
~
0xFFF00000
;
#else
T0
=
regs
->
spr
[
SRR1
]
&
~
0xFFFF0000
;
#endif
do_store_msr
();
#if defined (DEBUG_OP)
dump_rfi
();
...
...
target-ppc/op_helper.c
浏览文件 @
4b3686fa
...
...
@@ -127,11 +127,14 @@ void do_load_msr (void)
void
do_store_msr
(
void
)
{
#if 1 // TRY
if
(((
T0
>>
MSR_IR
)
&
0x01
)
!=
msr_ir
||
((
T0
>>
MSR_DR
)
&
0x01
)
!=
msr_dr
)
{
/* Flush all tlb when changing translation mode or privilege level */
((
T0
>>
MSR_DR
)
&
0x01
)
!=
msr_dr
||
((
T0
>>
MSR_PR
)
&
0x01
)
!=
msr_pr
)
{
do_tlbia
();
}
#endif
msr_pow
=
(
T0
>>
MSR_POW
)
&
0x03
;
msr_ile
=
(
T0
>>
MSR_ILE
)
&
0x01
;
msr_ee
=
(
T0
>>
MSR_EE
)
&
0x01
;
...
...
@@ -157,14 +160,18 @@ void do_sraw (void)
xer_ca
=
0
;
if
(
T1
&
0x20
)
{
ret
=
(
-
1
)
*
(
T0
>>
31
);
if
(
ret
<
0
)
if
(
ret
<
0
&&
(
T0
&
~
0x80000000
)
!=
0
)
xer_ca
=
1
;
#if 1 // TRY
}
else
if
(
T1
==
0
)
{
ret
=
T0
;
#endif
}
else
{
ret
=
(
int32_t
)
T0
>>
(
T1
&
0x1f
);
if
(
ret
<
0
&&
((
int32_t
)
T0
&
((
1
<<
T1
)
-
1
))
!=
0
)
xer_ca
=
1
;
}
(
int32_t
)
T0
=
ret
;
T0
=
ret
;
}
/* Floating point operations helpers */
...
...
@@ -267,14 +274,24 @@ void do_fctiwz (void)
fesetround
(
cround
);
}
void
do_fnmadd
(
void
)
{
FT0
=
-
((
FT0
*
FT1
)
+
FT2
);
}
void
do_fnmsub
(
void
)
{
FT0
=
-
((
FT0
*
FT1
)
-
FT2
);
}
void
do_fnmadds
(
void
)
{
FT
S
0
=
-
((
FTS0
*
FTS1
)
+
FTS2
);
FT0
=
-
((
FTS0
*
FTS1
)
+
FTS2
);
}
void
do_fnmsubs
(
void
)
{
FT
S
0
=
-
((
FTS0
*
FTS1
)
-
FTS2
);
FT0
=
-
((
FTS0
*
FTS1
)
-
FTS2
);
}
void
do_fsqrt
(
void
)
...
...
@@ -307,7 +324,6 @@ void do_fsel (void)
void
do_fcmpu
(
void
)
{
env
->
fpscr
[
4
]
&=
~
0x1
;
if
(
isnan
(
FT0
)
||
isnan
(
FT1
))
{
T0
=
0x01
;
env
->
fpscr
[
4
]
|=
0x1
;
...
...
@@ -319,7 +335,7 @@ void do_fcmpu (void)
}
else
{
T0
=
0x02
;
}
env
->
fpscr
[
3
]
|
=
T0
;
env
->
fpscr
[
3
]
=
T0
;
}
void
do_fcmpo
(
void
)
...
...
@@ -343,7 +359,7 @@ void do_fcmpo (void)
}
else
{
T0
=
0x02
;
}
env
->
fpscr
[
3
]
|
=
T0
;
env
->
fpscr
[
3
]
=
T0
;
}
void
do_fabs
(
void
)
...
...
@@ -359,6 +375,12 @@ void do_fnabs (void)
/* Instruction cache invalidation helper */
#define ICACHE_LINE_SIZE 32
void
do_check_reservation
(
void
)
{
if
((
env
->
reserve
&
~
(
ICACHE_LINE_SIZE
-
1
))
==
T0
)
env
->
reserve
=
-
1
;
}
void
do_icbi
(
void
)
{
/* Invalidate one cache line */
...
...
@@ -377,6 +399,69 @@ void do_tlbie (void)
tlb_flush_page
(
env
,
T0
);
}
void
do_store_sr
(
uint32_t
srnum
)
{
#if defined (DEBUG_OP)
dump_store_sr
(
srnum
);
#endif
#if 0 // TRY
{
uint32_t base, page;
base = srnum << 28;
for (page = base; page != base + 0x100000000; page += 0x1000)
tlb_flush_page(env, page);
}
#else
tlb_flush
(
env
,
1
);
#endif
env
->
sr
[
srnum
]
=
T0
;
}
/* For BATs, we may not invalidate any TLBs if the change is only on
* protection bits for user mode.
*/
void
do_store_ibat
(
int
ul
,
int
nr
)
{
#if defined (DEBUG_OP)
dump_store_ibat
(
ul
,
nr
);
#endif
#if 0 // TRY
{
uint32_t base, length, page;
base = env->IBAT[0][nr];
length = (((base >> 2) & 0x000007FF) + 1) << 17;
base &= 0xFFFC0000;
for (page = base; page != base + length; page += 0x1000)
tlb_flush_page(env, page);
}
#else
tlb_flush
(
env
,
1
);
#endif
env
->
IBAT
[
ul
][
nr
]
=
T0
;
}
void
do_store_dbat
(
int
ul
,
int
nr
)
{
#if defined (DEBUG_OP)
dump_store_dbat
(
ul
,
nr
);
#endif
#if 0 // TRY
{
uint32_t base, length, page;
base = env->DBAT[0][nr];
length = (((base >> 2) & 0x000007FF) + 1) << 17;
base &= 0xFFFC0000;
for (page = base; page != base + length; page += 0x1000)
tlb_flush_page(env, page);
}
#else
tlb_flush
(
env
,
1
);
#endif
env
->
DBAT
[
ul
][
nr
]
=
T0
;
}
/*****************************************************************************/
/* Special helpers for debug */
extern
FILE
*
stdout
;
...
...
@@ -389,7 +474,7 @@ void dump_state (void)
void
dump_rfi
(
void
)
{
#if 0
printf("Return from interrupt
%d => 0x%08x\n", pos
, env->nip);
printf("Return from interrupt
=> 0x%08x\n"
, env->nip);
// cpu_ppc_dump_state(env, stdout, 0);
#endif
}
...
...
target-ppc/op_template.h
浏览文件 @
4b3686fa
...
...
@@ -175,10 +175,7 @@ void OPPROTO glue(op_load_sr, REG)(void)
void
OPPROTO
glue
(
op_store_sr
,
REG
)(
void
)
{
#if defined (DEBUG_OP)
dump_store_sr
(
REG
);
#endif
env
->
sr
[
REG
]
=
T0
;
do_store_sr
(
REG
);
RETURN
();
}
#endif
...
...
target-ppc/translate.c
浏览文件 @
4b3686fa
...
...
@@ -28,8 +28,6 @@
#include "disas.h"
//#define DO_SINGLE_STEP
//#define DO_STEP_FLUSH
//#define DEBUG_DISAS
//#define PPC_DEBUG_DISAS
enum
{
...
...
@@ -639,7 +637,7 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
}
gen_op_load_gpr_T0
(
rS
(
ctx
->
opcode
));
if
(
uimm
!=
0
)
gen_op_xori
(
UIMM
(
ctx
->
opcode
)
);
gen_op_xori
(
uimm
);
gen_op_store_T0_gpr
(
rA
(
ctx
->
opcode
));
}
...
...
@@ -654,7 +652,7 @@ GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
}
gen_op_load_gpr_T0
(
rS
(
ctx
->
opcode
));
if
(
uimm
!=
0
)
gen_op_xori
(
UIMM
(
ctx
->
opcode
)
<<
16
);
gen_op_xori
(
uimm
<<
16
);
gen_op_store_T0_gpr
(
rA
(
ctx
->
opcode
));
}
...
...
@@ -682,25 +680,29 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
mb
=
MB
(
ctx
->
opcode
);
me
=
ME
(
ctx
->
opcode
);
gen_op_load_gpr_T0
(
rS
(
ctx
->
opcode
));
#if 1 // TRY
if
(
sh
==
0
)
{
gen_op_andi_
(
MASK
(
mb
,
me
));
goto
store
;
}
#endif
if
(
mb
==
0
)
{
if
(
me
==
31
)
{
gen_op_rotlwi
(
sh
);
goto
store
;
#if 0
} else if (me == (31 - sh)) {
gen_op_slwi(sh);
goto store;
}
else
if
(
sh
==
0
)
{
gen_op_andi_
(
MASK
(
0
,
me
));
goto
store
;
#endif
}
}
else
if
(
me
==
31
)
{
#if 0
if (sh == (32 - mb)) {
gen_op_srwi(mb);
goto store;
}
else
if
(
sh
==
0
)
{
gen_op_andi_
(
MASK
(
mb
,
31
));
goto
store
;
}
#endif
}
gen_op_rlwinm
(
sh
,
MASK
(
mb
,
me
));
store:
...
...
@@ -1268,12 +1270,16 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
/* stswi */
GEN_HANDLER
(
stswi
,
0x1F
,
0x15
,
0x16
,
0x00000001
,
PPC_INTEGER
)
{
int
nb
=
NB
(
ctx
->
opcode
);
if
(
rA
(
ctx
->
opcode
)
==
0
)
{
gen_op_set_T0
(
0
);
}
else
{
gen_op_load_gpr_T0
(
rA
(
ctx
->
opcode
));
}
gen_op_set_T1
(
NB
(
ctx
->
opcode
));
if
(
nb
==
0
)
nb
=
32
;
gen_op_set_T1
(
nb
);
op_ldsts
(
stsw
,
rS
(
ctx
->
opcode
));
}
...
...
@@ -1931,7 +1937,6 @@ GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
/* We need to update the time base before reading it */
switch
(
sprn
)
{
case
V_TBL
:
/* TBL is still in T0 */
gen_op_load_tbl
();
break
;
case
V_TBU
:
...
...
@@ -2007,135 +2012,135 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
break
;
case
IBAT0U
:
gen_op_store_ibat
(
0
,
0
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT1U
:
gen_op_store_ibat
(
0
,
1
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT2U
:
gen_op_store_ibat
(
0
,
2
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT3U
:
gen_op_store_ibat
(
0
,
3
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT4U
:
gen_op_store_ibat
(
0
,
4
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT5U
:
gen_op_store_ibat
(
0
,
5
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT6U
:
gen_op_store_ibat
(
0
,
6
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT7U
:
gen_op_store_ibat
(
0
,
7
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT0L
:
gen_op_store_ibat
(
1
,
0
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT1L
:
gen_op_store_ibat
(
1
,
1
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT2L
:
gen_op_store_ibat
(
1
,
2
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT3L
:
gen_op_store_ibat
(
1
,
3
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT4L
:
gen_op_store_ibat
(
1
,
4
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT5L
:
gen_op_store_ibat
(
1
,
5
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT6L
:
gen_op_store_ibat
(
1
,
6
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
IBAT7L
:
gen_op_store_ibat
(
1
,
7
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT0U
:
gen_op_store_dbat
(
0
,
0
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT1U
:
gen_op_store_dbat
(
0
,
1
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT2U
:
gen_op_store_dbat
(
0
,
2
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT3U
:
gen_op_store_dbat
(
0
,
3
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT4U
:
gen_op_store_dbat
(
0
,
4
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT5U
:
gen_op_store_dbat
(
0
,
5
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT6U
:
gen_op_store_dbat
(
0
,
6
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT7U
:
gen_op_store_dbat
(
0
,
7
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT0L
:
gen_op_store_dbat
(
1
,
0
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT1L
:
gen_op_store_dbat
(
1
,
1
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT2L
:
gen_op_store_dbat
(
1
,
2
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT3L
:
gen_op_store_dbat
(
1
,
3
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT4L
:
gen_op_store_dbat
(
1
,
4
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT5L
:
gen_op_store_dbat
(
1
,
5
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT6L
:
gen_op_store_dbat
(
1
,
6
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
DBAT7L
:
gen_op_store_dbat
(
1
,
7
);
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
SDR1
:
gen_op_store_sdr1
();
gen_op_tlbia
(
);
RET_MTMSR
(
ctx
);
break
;
case
O_TBL
:
gen_op_store_tbl
();
...
...
@@ -2146,6 +2151,11 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
case
DECR
:
gen_op_store_decr
();
break
;
#if 0
case HID0:
gen_op_store_hid0();
break;
#endif
default:
gen_op_store_spr
(
sprn
);
break
;
...
...
@@ -2236,6 +2246,7 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
gen_op_add
();
}
op_dcbz
();
gen_op_check_reservation
();
}
/* icbi */
...
...
@@ -2302,10 +2313,6 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
}
gen_op_load_gpr_T0
(
rS
(
ctx
->
opcode
));
gen_op_store_sr
(
SR
(
ctx
->
opcode
));
#if 0
gen_op_tlbia();
RET_MTMSR(ctx);
#endif
#endif
}
...
...
@@ -2322,7 +2329,6 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
gen_op_load_gpr_T0
(
rS
(
ctx
->
opcode
));
gen_op_load_gpr_T1
(
rB
(
ctx
->
opcode
));
gen_op_store_srin
();
gen_op_tlbia
();
#endif
}
...
...
@@ -2341,6 +2347,7 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
return
;
}
gen_op_tlbia
();
RET_MTMSR
(
ctx
);
#endif
}
...
...
@@ -2356,6 +2363,7 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
}
gen_op_load_gpr_T0
(
rB
(
ctx
->
opcode
));
gen_op_tlbie
();
RET_MTMSR
(
ctx
);
#endif
}
...
...
@@ -2372,6 +2380,7 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM)
/* This has no effect: it should ensure that all previous
* tlbie have completed
*/
RET_MTMSR
(
ctx
);
#endif
}
...
...
@@ -2692,59 +2701,78 @@ static void init_spr_rights (uint32_t pvr)
spr_set_rights
(
DBAT3U
,
SPR_SR
|
SPR_SW
);
/* DBAT3L (SPR 543) */
spr_set_rights
(
DBAT3L
,
SPR_SR
|
SPR_SW
);
/* DABR (SPR 1013) */
spr_set_rights
(
DABR
,
SPR_SR
|
SPR_SW
);
/* FPECR (SPR 1022) */
spr_set_rights
(
FPECR
,
SPR_SR
|
SPR_SW
);
/* PIR (SPR 1023) */
/* Special registers for PPC 604 */
if
((
pvr
&
0xFFFF0000
)
==
0x00040000
)
{
/* IABR */
spr_set_rights
(
IABR
,
SPR_SR
|
SPR_SW
);
/* DABR (SPR 1013) */
spr_set_rights
(
DABR
,
SPR_SR
|
SPR_SW
);
/* HID0 */
spr_set_rights
(
HID0
,
SPR_SR
|
SPR_SW
);
/* PIR */
spr_set_rights
(
PIR
,
SPR_SR
|
SPR_SW
);
/* PMC1 */
spr_set_rights
(
PMC1
,
SPR_SR
|
SPR_SW
);
/* PMC2 */
spr_set_rights
(
PMC2
,
SPR_SR
|
SPR_SW
);
/* MMCR0 */
spr_set_rights
(
MMCR0
,
SPR_SR
|
SPR_SW
);
/* SIA */
spr_set_rights
(
SIA
,
SPR_SR
|
SPR_SW
);
/* SDA */
spr_set_rights
(
SDA
,
SPR_SR
|
SPR_SW
);
}
/* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */
if
((
pvr
&
0xFFFF0000
)
==
0x00080000
||
(
pvr
&
0xFFFF0000
)
==
0x70000000
)
{
/* HID0 */
spr_set_rights
(
SPR_ENCODE
(
1008
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
HID0
,
SPR_SR
|
SPR_SW
);
/* HID1 */
spr_set_rights
(
SPR_ENCODE
(
1009
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
HID1
,
SPR_SR
|
SPR_SW
);
/* IABR */
spr_set_rights
(
SPR_ENCODE
(
1010
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
IABR
,
SPR_SR
|
SPR_SW
);
/* ICTC */
spr_set_rights
(
SPR_ENCODE
(
1019
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
ICTC
,
SPR_SR
|
SPR_SW
);
/* L2CR */
spr_set_rights
(
SPR_ENCODE
(
1017
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
L2CR
,
SPR_SR
|
SPR_SW
);
/* MMCR0 */
spr_set_rights
(
SPR_ENCODE
(
952
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
MMCR0
,
SPR_SR
|
SPR_SW
);
/* MMCR1 */
spr_set_rights
(
SPR_ENCODE
(
956
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
MMCR1
,
SPR_SR
|
SPR_SW
);
/* PMC1 */
spr_set_rights
(
SPR_ENCODE
(
953
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
PMC1
,
SPR_SR
|
SPR_SW
);
/* PMC2 */
spr_set_rights
(
SPR_ENCODE
(
954
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
PMC2
,
SPR_SR
|
SPR_SW
);
/* PMC3 */
spr_set_rights
(
SPR_ENCODE
(
957
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
PMC3
,
SPR_SR
|
SPR_SW
);
/* PMC4 */
spr_set_rights
(
SPR_ENCODE
(
958
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
PMC4
,
SPR_SR
|
SPR_SW
);
/* SIA */
spr_set_rights
(
SPR_ENCODE
(
955
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
SIA
,
SPR_SR
|
SPR_SW
);
/* SDA */
spr_set_rights
(
SDA
,
SPR_SR
|
SPR_SW
);
/* THRM1 */
spr_set_rights
(
SPR_ENCODE
(
1020
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
THRM1
,
SPR_SR
|
SPR_SW
);
/* THRM2 */
spr_set_rights
(
SPR_ENCODE
(
1021
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
THRM2
,
SPR_SR
|
SPR_SW
);
/* THRM3 */
spr_set_rights
(
SPR_ENCODE
(
1022
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
THRM3
,
SPR_SR
|
SPR_SW
);
/* UMMCR0 */
spr_set_rights
(
SPR_ENCODE
(
936
)
,
SPR_UR
|
SPR_UW
);
spr_set_rights
(
UMMCR0
,
SPR_UR
|
SPR_UW
);
/* UMMCR1 */
spr_set_rights
(
SPR_ENCODE
(
940
)
,
SPR_UR
|
SPR_UW
);
spr_set_rights
(
UMMCR1
,
SPR_UR
|
SPR_UW
);
/* UPMC1 */
spr_set_rights
(
SPR_ENCODE
(
937
),
SPR_UR
|
SPR_UW
);
spr_set_rights
(
UPMC1
,
SPR_UR
|
SPR_UW
);
/* UPMC2 */
spr_set_rights
(
SPR_ENCODE
(
938
),
SPR_UR
|
SPR_UW
);
spr_set_rights
(
UPMC2
,
SPR_UR
|
SPR_UW
);
/* UPMC3 */
spr_set_rights
(
SPR_ENCODE
(
941
),
SPR_UR
|
SPR_UW
);
spr_set_rights
(
UPMC3
,
SPR_UR
|
SPR_UW
);
/* UPMC4 */
spr_set_rights
(
SPR_ENCODE
(
942
),
SPR_UR
|
SPR_UW
);
spr_set_rights
(
UPMC4
,
SPR_UR
|
SPR_UW
);
/* USIA */
spr_set_rights
(
SPR_ENCODE
(
939
),
SPR_UR
|
SPR_UW
);
spr_set_rights
(
USIA
,
SPR_UR
|
SPR_UW
);
}
/* MPC755 has special registers */
if
(
pvr
==
0x00083100
)
{
...
...
@@ -2789,23 +2817,23 @@ static void init_spr_rights (uint32_t pvr)
/* DBAT7L */
spr_set_rights
(
DBAT7L
,
SPR_SR
|
SPR_SW
);
/* DMISS */
spr_set_rights
(
SPR_ENCODE
(
976
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
DMISS
,
SPR_SR
|
SPR_SW
);
/* DCMP */
spr_set_rights
(
SPR_ENCODE
(
977
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
DCMP
,
SPR_SR
|
SPR_SW
);
/* DHASH1 */
spr_set_rights
(
SPR_ENCODE
(
978
)
,
SPR_SR
|
SPR_SW
);
spr_set_rights
(
DHASH1
,
SPR_SR
|
SPR_SW
);
/* DHASH2 */
spr_set_rights
(
SPR_ENCODE
(
979
)
,
SPR_SR
|
SPR_SW
);
spr_set_rights
(
DHASH2
,
SPR_SR
|
SPR_SW
);
/* IMISS */
spr_set_rights
(
SPR_ENCODE
(
980
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
IMISS
,
SPR_SR
|
SPR_SW
);
/* ICMP */
spr_set_rights
(
SPR_ENCODE
(
981
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
ICMP
,
SPR_SR
|
SPR_SW
);
/* RPA */
spr_set_rights
(
SPR_ENCODE
(
982
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
RPA
,
SPR_SR
|
SPR_SW
);
/* HID2 */
spr_set_rights
(
SPR_ENCODE
(
1011
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
HID2
,
SPR_SR
|
SPR_SW
);
/* L2PM */
spr_set_rights
(
SPR_ENCODE
(
1016
),
SPR_SR
|
SPR_SW
);
spr_set_rights
(
L2PM
,
SPR_SR
|
SPR_SW
);
}
}
...
...
@@ -2941,10 +2969,9 @@ CPUPPCState *cpu_ppc_init(void)
cpu_exec_init
();
env
=
malloc
(
sizeof
(
CPUPPCState
));
env
=
qemu_mallocz
(
sizeof
(
CPUPPCState
));
if
(
!
env
)
return
NULL
;
memset
(
env
,
0
,
sizeof
(
CPUPPCState
));
#if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE)
setup_machine
(
env
,
0
);
#else
...
...
@@ -2953,22 +2980,34 @@ CPUPPCState *cpu_ppc_init(void)
// env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
// env->spr[PVR] = 0x00070100; /* IBM 750FX */
#endif
if
(
create_ppc_proc
(
ppc_opcodes
,
env
->
spr
[
PVR
])
<
0
)
return
NULL
;
init_spr_rights
(
env
->
spr
[
PVR
]);
tlb_flush
(
env
,
1
);
#if defined (DO_SINGLE_STEP)
/* Single step trace mode */
msr_se
=
1
;
#endif
msr_fp
=
1
;
/* Allow floating point exceptions */
msr_me
=
1
;
/* Allow machine check exceptions */
#if defined(CONFIG_USER_ONLY)
msr_pr
=
1
;
cpu_ppc_register
(
env
,
0x00080000
);
#else
env
->
nip
=
0xFFFFFFFC
;
#endif
env
->
access_type
=
ACCESS_INT
;
return
env
;
}
int
cpu_ppc_register
(
CPUPPCState
*
env
,
uint32_t
pvr
)
{
env
->
spr
[
PVR
]
=
pvr
;
if
(
create_ppc_proc
(
ppc_opcodes
,
env
->
spr
[
PVR
])
<
0
)
return
-
1
;
init_spr_rights
(
env
->
spr
[
PVR
]);
return
0
;
}
void
cpu_ppc_close
(
CPUPPCState
*
env
)
{
/* Should also remove all opcode tables... */
...
...
@@ -3047,26 +3086,26 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
}
}
/* Is opcode *REALLY* valid ? */
if
((
ctx
.
opcode
&
handler
->
inval
)
!=
0
)
{
if
(
loglevel
>
0
)
{
if
(
handler
->
handler
==
&
gen_invalid
)
{
if
(
loglevel
>
0
)
{
fprintf
(
logfile
,
"invalid/unsupported opcode: "
"%02x -%02x - %02x (%08x) 0x%08x
\n
"
,
"%02x - %02x - %02x (%08x) 0x%08x %d
\n
"
,
opc1
(
ctx
.
opcode
),
opc2
(
ctx
.
opcode
),
opc3
(
ctx
.
opcode
),
ctx
.
opcode
,
ctx
.
nip
-
4
);
opc3
(
ctx
.
opcode
),
ctx
.
opcode
,
ctx
.
nip
-
4
,
msr_ir
);
}
else
{
printf
(
"invalid/unsupported opcode: "
"%02x - %02x - %02x (%08x) 0x%08x %d
\n
"
,
opc1
(
ctx
.
opcode
),
opc2
(
ctx
.
opcode
),
opc3
(
ctx
.
opcode
),
ctx
.
opcode
,
ctx
.
nip
-
4
,
msr_ir
);
}
}
else
{
if
((
ctx
.
opcode
&
handler
->
inval
)
!=
0
)
{
if
(
loglevel
>
0
)
{
fprintf
(
logfile
,
"invalid bits: %08x for opcode: "
"%02x -%02x - %02x (0x%08x) (0x%08x)
\n
"
,
ctx
.
opcode
&
handler
->
inval
,
opc1
(
ctx
.
opcode
),
opc2
(
ctx
.
opcode
),
opc3
(
ctx
.
opcode
),
ctx
.
opcode
,
ctx
.
nip
-
4
);
}
}
else
{
if
(
handler
->
handler
==
&
gen_invalid
)
{
printf
(
"invalid/unsupported opcode: "
"%02x -%02x - %02x (%08x) 0x%08x
\n
"
,
opc1
(
ctx
.
opcode
),
opc2
(
ctx
.
opcode
),
opc3
(
ctx
.
opcode
),
ctx
.
opcode
,
ctx
.
nip
-
4
);
}
else
{
printf
(
"invalid bits: %08x for opcode: "
"%02x -%02x - %02x (0x%08x) (0x%08x)
\n
"
,
...
...
@@ -3074,11 +3113,11 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
opc2
(
ctx
.
opcode
),
opc3
(
ctx
.
opcode
),
ctx
.
opcode
,
ctx
.
nip
-
4
);
}
RET_INVAL
(
ctxp
);
break
;
}
(
*
gen_invalid
)(
&
ctx
);
}
else
{
(
*
(
handler
->
handler
))(
&
ctx
);
}
(
*
(
handler
->
handler
))(
&
ctx
);
/* Check trace mode exceptions */
if
((
msr_be
&&
ctx
.
exception
==
EXCP_BRANCH
)
||
/* Check in single step trace mode
...
...
@@ -3126,7 +3165,6 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
}
else
{
tb
->
size
=
ctx
.
nip
-
pc_start
;
}
env
->
access_type
=
ACCESS_INT
;
#ifdef DEBUG_DISAS
if
(
loglevel
&
CPU_LOG_TB_CPU
)
{
fprintf
(
logfile
,
"---------------- excp: %04x
\n
"
,
ctx
.
exception
);
...
...
@@ -3143,6 +3181,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
fprintf
(
logfile
,
"
\n
"
);
}
#endif
env
->
access_type
=
ACCESS_INT
;
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录