Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
NEMU
提交
b973f41a
N
NEMU
项目概览
OpenXiangShan
/
NEMU
大约 1 年 前同步成功
通知
7
Star
171
Fork
67
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
NEMU
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b973f41a
编写于
1月 27, 2019
作者:
Z
Zihao Yu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
mips32: add tlb
上级
191c4883
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
174 addition
and
7 deletion
+174
-7
src/isa/mips32/exec/all-instr.h
src/isa/mips32/exec/all-instr.h
+3
-0
src/isa/mips32/exec/exec.c
src/isa/mips32/exec/exec.c
+12
-2
src/isa/mips32/exec/system.c
src/isa/mips32/exec/system.c
+22
-1
src/isa/mips32/include/isa/intr.h
src/isa/mips32/include/isa/intr.h
+5
-0
src/isa/mips32/include/isa/reg.h
src/isa/mips32/include/isa/reg.h
+11
-0
src/isa/mips32/intr.c
src/isa/mips32/intr.c
+11
-1
src/isa/mips32/mmu.c
src/isa/mips32/mmu.c
+110
-3
未找到文件。
src/isa/mips32/exec/all-instr.h
浏览文件 @
b973f41a
...
...
@@ -51,3 +51,6 @@ make_EHelper(syscall);
make_EHelper
(
eret
);
make_EHelper
(
mfc0
);
make_EHelper
(
mtc0
);
make_EHelper
(
tlbwr
);
make_EHelper
(
tlbwi
);
make_EHelper
(
tlbp
);
src/isa/mips32/exec/exec.c
浏览文件 @
b973f41a
#include "cpu/exec.h"
#include "all-instr.h"
#include <setjmp.h>
static
OpcodeEntry
special_table
[
64
]
=
{
/* b000 */
IDEX
(
shift
,
sll
),
EMPTY
,
IDEX
(
shift
,
srl
),
IDEX
(
shift
,
sra
),
IDEX
(
R
,
sll
),
EMPTY
,
IDEX
(
R
,
srl
),
IDEX
(
R
,
sra
),
...
...
@@ -48,8 +49,8 @@ static OpcodeEntry cop0_table [16] = {
};
static
OpcodeEntry
cop0co_table
[
64
]
=
{
/* b000 */
EMPTY
,
EMPTY
,
E
MPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
/* b001 */
E
MPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
/* b000 */
EMPTY
,
EMPTY
,
E
X
(
tlbwi
),
EMPTY
,
EMPTY
,
EMPTY
,
EX
(
tlbwr
)
,
EMPTY
,
/* b001 */
E
X
(
tlbp
)
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
/* b010 */
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
/* b011 */
EX
(
eret
),
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
/* b100 */
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
EMPTY
,
...
...
@@ -79,6 +80,15 @@ static OpcodeEntry opcode_table [64] = {
};
make_EHelper
(
isa
)
{
extern
jmp_buf
intr_buf
;
int
setjmp_ret
;
if
((
setjmp_ret
=
setjmp
(
intr_buf
))
!=
0
)
{
// exception
int
exce_code
=
setjmp_ret
-
1
;
void
raise_intr
(
uint8_t
,
vaddr_t
);
raise_intr
(
exce_code
,
cpu
.
pc
);
return
;
}
decinfo
.
isa
.
instr
.
val
=
instr_fetch
(
eip
,
4
);
decinfo
.
width
=
opcode_table
[
decinfo
.
isa
.
instr
.
opcode
].
width
;
idex
(
eip
,
&
opcode_table
[
decinfo
.
isa
.
instr
.
opcode
]);
...
...
src/isa/mips32/exec/system.c
浏览文件 @
b973f41a
#include "cpu/exec.h"
#include "isa/intr.h"
void
raise_intr
(
uint8_t
,
vaddr_t
);
#define EX_SYSCALL 8
make_EHelper
(
syscall
)
{
#if defined(DIFF_TEST)
...
...
@@ -27,6 +27,8 @@ make_EHelper(mfc0) {
uint32_t
val
;
switch
(
id_dest
->
reg
)
{
case
0
:
val
=
cpu
.
index
;
print_asm
(
"mfc0 %s, index"
,
id_src2
->
str
);
break
;
case
10
:
val
=
cpu
.
entryhi
.
val
;
print_asm
(
"mfc0 %s, entryhi"
,
id_src2
->
str
);
break
;
case
12
:
val
=
cpu
.
status
;
print_asm
(
"mfc0 %s, status"
,
id_src2
->
str
);
break
;
case
13
:
val
=
cpu
.
cause
;
print_asm
(
"mfc0 %s, cause"
,
id_src2
->
str
);
break
;
case
14
:
val
=
cpu
.
epc
;
print_asm
(
"mfc0 %s, epc"
,
id_src2
->
str
);
break
;
...
...
@@ -39,9 +41,28 @@ make_EHelper(mfc0) {
make_EHelper
(
mtc0
)
{
switch
(
id_dest
->
reg
)
{
case
0
:
cpu
.
index
=
id_src2
->
val
;
print_asm
(
"mtc0 %s, index"
,
id_src2
->
str
);
break
;
case
2
:
cpu
.
entrylo0
=
id_src2
->
val
;
print_asm
(
"mtc0 %s, entrylo0"
,
id_src2
->
str
);
break
;
case
3
:
cpu
.
entrylo1
=
id_src2
->
val
;
print_asm
(
"mtc0 %s, entrylo1"
,
id_src2
->
str
);
break
;
case
10
:
cpu
.
entryhi
.
val
=
id_src2
->
val
;
print_asm
(
"mtc0 %s, entryhi"
,
id_src2
->
str
);
break
;
case
12
:
cpu
.
status
=
id_src2
->
val
;
print_asm
(
"mtc0 %s, status"
,
id_src2
->
str
);
break
;
case
13
:
cpu
.
cause
=
id_src2
->
val
;
print_asm
(
"mtc0 %s, cause"
,
id_src2
->
str
);
break
;
case
14
:
cpu
.
epc
=
id_src2
->
val
;
print_asm
(
"mtc0 %s, epc"
,
id_src2
->
str
);
break
;
default:
assert
(
0
);
}
}
make_EHelper
(
tlbwr
)
{
extern
void
tlbwr
(
void
);
tlbwr
();
}
make_EHelper
(
tlbwi
)
{
extern
void
tlbwi
(
void
);
tlbwi
();
}
make_EHelper
(
tlbp
)
{
extern
void
tlbp
(
void
);
tlbp
();
}
src/isa/mips32/include/isa/intr.h
浏览文件 @
b973f41a
#include "reg.h"
#define EX_SYSCALL 8
#define EX_TLB_LD 2
#define EX_TLB_ST 3
#define TLB_REFILL 0x80
static
inline
bool
isa_istatus
(
void
)
{
return
false
;
}
src/isa/mips32/include/isa/reg.h
浏览文件 @
b973f41a
...
...
@@ -20,6 +20,17 @@ typedef struct {
vaddr_t
pc
;
uint32_t
epc
;
union
{
struct
{
uint32_t
ASID
:
8
;
uint32_t
pad
:
5
;
uint32_t
VPN2
:
19
;
};
uint32_t
val
;
}
entryhi
;
uint32_t
entrylo0
,
entrylo1
;
uint32_t
index
;
bool
INTR
;
}
CPU_state
;
...
...
src/isa/mips32/intr.c
浏览文件 @
b973f41a
#include "cpu/rtl.h"
#include "isa/intr.h"
#include <setjmp.h>
#define EX_ENTRY 0x80000180
...
...
@@ -8,8 +10,16 @@ void raise_intr(uint8_t NO, vaddr_t epc) {
*/
//TODO();
vaddr_t
target
=
(
NO
&
TLB_REFILL
)
?
0x80000000
:
EX_ENTRY
;
NO
&=
~
TLB_REFILL
;
cpu
.
cause
=
NO
<<
2
;
cpu
.
epc
=
epc
;
rtl_j
(
EX_ENTRY
);
rtl_j
(
target
);
}
jmp_buf
intr_buf
;
void
longjmp_raise_intr
(
uint8_t
NO
)
{
longjmp
(
intr_buf
,
NO
+
1
);
}
src/isa/mips32/mmu.c
浏览文件 @
b973f41a
#include "nemu.h"
#include "memory/memory.h"
#include "isa/intr.h"
#include <stdlib.h>
#include <time.h>
#define NR_TLB 128
typedef
union
{
struct
{
uint32_t
ASID
:
8
;
uint32_t
pad
:
5
;
uint32_t
VPN2
:
19
;
};
uint32_t
val
;
}
EntryHi
;
typedef
union
{
struct
{
uint32_t
G
:
1
;
uint32_t
V
:
1
;
uint32_t
D
:
1
;
uint32_t
C
:
3
;
uint32_t
PFN
:
24
;
uint32_t
pad
:
2
;
};
uint32_t
val
;
}
EntryLo
;
struct
{
EntryHi
hi
;
EntryLo
lo
[
2
];
}
tlb
[
NR_TLB
];
void
init_mmu
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
NR_TLB
;
i
++
)
{
tlb
[
i
].
lo
[
0
].
V
=
tlb
[
i
].
lo
[
1
].
V
=
0
;
}
srand
(
time
(
0
));
}
void
update_tlb
(
int
idx
)
{
tlb
[
idx
].
hi
.
val
=
cpu
.
entryhi
.
val
;
tlb
[
idx
].
lo
[
0
].
val
=
cpu
.
entrylo0
;
tlb
[
idx
].
lo
[
1
].
val
=
cpu
.
entrylo1
;
}
void
tlbwr
(
void
)
{
update_tlb
(
rand
()
%
NR_TLB
);
}
void
tlbwi
(
void
)
{
update_tlb
(
cpu
.
index
%
NR_TLB
);
}
void
tlbp
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
NR_TLB
;
i
++
)
{
if
(
tlb
[
i
].
hi
.
VPN2
==
cpu
.
entryhi
.
VPN2
)
{
Log
(
"match, i = %d"
,
i
);
cpu
.
index
=
i
;
return
;
}
}
cpu
.
index
=
-
1
;
}
extern
void
longjmp_raise_intr
(
uint8_t
NO
);
static
inline
int32_t
search_ppn
(
vaddr_t
addr
,
bool
write
)
{
union
{
struct
{
uint32_t
offset
:
12
;
uint32_t
lo_idx
:
1
;
uint32_t
vpn
:
19
;
};
uint32_t
val
;
}
a
;
a
.
val
=
addr
;
int
i
;
for
(
i
=
0
;
i
<
NR_TLB
;
i
++
)
{
if
(
tlb
[
i
].
hi
.
VPN2
==
a
.
vpn
)
{
if
(
!
tlb
[
i
].
lo
[
a
.
lo_idx
].
V
)
{
cpu
.
entryhi
.
VPN2
=
a
.
vpn
;
// Log("tlb[%d] invalid at cpu.pc = 0x%08x, badaddr = 0x%08x", i, cpu.pc, addr);
longjmp_raise_intr
(
write
?
EX_TLB_ST
:
EX_TLB_LD
);
return
-
1
;
}
//Assert(tlb[i].lo[a.lo_idx].V, "cpu.pc = 0x%08x, addr = 0x%08x, lo0 = 0x%08x, lo1 = 0x%08x",
// cpu.pc, addr, tlb[i].lo[0].val, tlb[i].lo[1].val);
return
tlb
[
i
].
lo
[
a
.
lo_idx
].
PFN
;
}
}
cpu
.
entryhi
.
VPN2
=
a
.
vpn
;
// Log("tlb refill at cpu.pc = 0x%08x, badaddr = 0x%08x", cpu.pc, addr);
longjmp_raise_intr
(
TLB_REFILL
|
(
write
?
EX_TLB_ST
:
EX_TLB_LD
));
return
-
1
;
}
static
inline
paddr_t
va2pa
(
vaddr_t
addr
,
bool
write
)
{
if
((
addr
&
0xa0000000u
)
==
0xa0000000u
)
{
return
addr
&
~
0xa0000000u
;
}
if
((
addr
&
0x80000000u
)
==
0
)
{
int32_t
ppn
=
search_ppn
(
addr
,
write
);
addr
=
(
addr
&
0xfff
)
|
(
ppn
<<
12
);
}
static
inline
paddr_t
va2pa
(
vaddr_t
addr
)
{
return
addr
&
~
0x80000000u
;
}
uint32_t
isa_vaddr_read
(
vaddr_t
addr
,
int
len
)
{
return
paddr_read
(
va2pa
(
addr
),
len
);
return
paddr_read
(
va2pa
(
addr
,
false
),
len
);
}
void
isa_vaddr_write
(
vaddr_t
addr
,
uint32_t
data
,
int
len
)
{
paddr_write
(
va2pa
(
addr
),
data
,
len
);
paddr_write
(
va2pa
(
addr
,
true
),
data
,
len
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录