Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
nexus-am
提交
e4957617
N
nexus-am
项目概览
OpenXiangShan
/
nexus-am
9 个月 前同步成功
通知
0
Star
21
Fork
25
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
nexus-am
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
e4957617
编写于
11月 03, 2022
作者:
W
William Wang
提交者:
GitHub
11月 03, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #20 from OpenXiangShan/extra-pmp-test
Add extra RISC-V PMP tests
上级
cac71287
f5e7537a
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
384 addition
and
38 deletion
+384
-38
am/am.h
am/am.h
+3
-0
am/src/nemu/isa/riscv/cte64.c
am/src/nemu/isa/riscv/cte64.c
+7
-3
am/src/nemu/isa/riscv/vme.c
am/src/nemu/isa/riscv/vme.c
+43
-0
am/src/xs/isa/riscv/pmp.c
am/src/xs/isa/riscv/pmp.c
+2
-1
tests/amtest/src/main.c
tests/amtest/src/main.c
+1
-0
tests/amtest/src/tests/pmp.c
tests/amtest/src/tests/pmp.c
+164
-23
tests/amtest/src/tests/sv39.c
tests/amtest/src/tests/sv39.c
+164
-11
未找到文件。
am/am.h
浏览文件 @
e4957617
...
...
@@ -85,6 +85,9 @@ void _unprotect(_AddressSpace *as);
void
_map
(
_AddressSpace
*
as
,
void
*
va
,
void
*
pa
,
int
prot
);
_Context
*
_ucontext
(
_AddressSpace
*
as
,
_Area
kstack
,
void
*
entry
);
// hugepage map for xiangshan testing
void
_map_rv_hugepage
(
_AddressSpace
*
as
,
void
*
va
,
void
*
pa
,
int
prot
,
int
pagetable_level
);
// ================= Multi-Processor Extension (MPE) =================
int
_mpe_init
(
void
(
*
entry
)());
...
...
am/src/nemu/isa/riscv/cte64.c
浏览文件 @
e4957617
#include <riscv.h>
#include <nemu.h>
//
#include <printf.h>
#include <printf.h>
extern
void
__am_timervec
(
void
);
static
void
init_machine_exception
()
{
...
...
@@ -34,11 +34,15 @@ void __am_init_cte64() {
init_pmp
();
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS)
// protect 0x90000000 + 0x10000 for test purpose
enable_pmp
(
1
,
0x90000000
,
0x10000
,
0
,
0
);
printf
(
"enable_pmp
\n
"
);
enable_pmp
(
1
,
0x90000000
,
0x10000
,
0
,
0
);
// !rw
// printf("pmp NA inited\n");
// protect 0xb00000000 + 0x100
enable_pmp_TOR
(
4
,
0xb0000000
,
0x100
,
0
,
0
);
enable_pmp_TOR
(
3
,
0xb0000000
,
0x1000
,
0
,
0
);
// !rw
//printf("pmp TOR inited\n");
enable_pmp_TOR
(
5
,
0xb0004000
,
0x1000
,
0
,
PMP_R
);
// r,!w
enable_pmp_TOR
(
7
,
0xb0008000
,
0x1000
,
0
,
PMP_W
);
// !r, w
enable_pmp_TOR
(
9
,
0xb0010000
,
0x1000
,
0
,
0
);
// !r, w
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
// protect 0x210000000 + 0x10000 for test purpose
enable_pmp
(
1
,
0x2010000000
,
0x10000
,
0
,
0
);
...
...
am/src/nemu/isa/riscv/vme.c
浏览文件 @
e4957617
...
...
@@ -61,6 +61,7 @@ static inline void *new_page() {
memset
(
p
,
0
,
PGSIZE
);
return
p
;
}
/*
* Virtual Memory initialize
* pgalloc_f: pointer of page table memory allocater, must return page-aligned address
...
...
@@ -129,12 +130,14 @@ void _protect(_AddressSpace *as) {
void
_unprotect
(
_AddressSpace
*
as
)
{
}
/*
* get current satp
*/
void
__am_get_cur_as
(
_Context
*
c
)
{
c
->
pdir
=
(
vme_enable
?
(
void
*
)
get_satp
()
:
NULL
);
}
/*
* switch page table to the given context
*/
...
...
@@ -143,6 +146,7 @@ void __am_switch(_Context *c) {
set_satp
(
c
->
pdir
);
}
}
/*
* map va to pa with prot permission with page table root as
* Note that RISC-V allow hardware to fault when A and D bit is not set
...
...
@@ -168,6 +172,45 @@ void _map(_AddressSpace *as, void *va, void *pa, int prot) {
}
}
/*
* map va to pa with prot permission with page table root as
* pagetable_level indicates page table level to be used
* 0: basic 4KiB page
* 1: 2MiB megapage
* 2: 1GiB gigapage
* Note that RISC-V allow hardware to fault when A and D bit is not set
*/
void
_map_rv_hugepage
(
_AddressSpace
*
as
,
void
*
va
,
void
*
pa
,
int
prot
,
int
pagetable_level
)
{
int
hugepage_size
;
switch
(
pagetable_level
)
{
case
0
:
hugepage_size
=
PGSIZE
;
break
;
// 4KiB
case
1
:
hugepage_size
=
PGSIZE
*
512
;
break
;
// 2MiB
case
2
:
hugepage_size
=
PGSIZE
*
512
*
512
;
break
;
// 1GiB
default:
assert
(
0
);
}
assert
((
uintptr_t
)
va
%
hugepage_size
==
0
);
// printf("pa %lx sz %lx\n", pa, hugepage_size);
assert
((
uintptr_t
)
pa
%
hugepage_size
==
0
);
PTE
*
pg_base
=
as
->
ptr
;
PTE
*
pte
;
int
level
;
for
(
level
=
PTW_CONFIG
.
ptw_level
-
1
;
;
level
--
)
{
pte
=
&
pg_base
[
VPNi
(
PTW_CONFIG
,
(
uintptr_t
)
va
,
level
)];
pg_base
=
(
PTE
*
)
PTE_ADDR
(
*
pte
);
if
(
level
==
pagetable_level
)
break
;
if
(
!
(
*
pte
&
PTE_V
))
{
pg_base
=
new_page
();
*
pte
=
PTE_V
|
(
PN
(
pg_base
)
<<
10
);
}
}
int
hugepage_pn_shift
=
pagetable_level
*
9
;
if
(
!
(
*
pte
&
PTE_V
))
{
*
pte
=
PTE_V
|
prot
|
(
PN
(
pa
)
>>
hugepage_pn_shift
<<
hugepage_pn_shift
<<
10
);
}
printf
(
"map huge page level %d, pte value %lx
\n
"
,
pagetable_level
,
*
pte
);
}
_Context
*
_ucontext
(
_AddressSpace
*
as
,
_Area
kstack
,
void
*
entry
)
{
_Context
*
c
=
(
_Context
*
)
kstack
.
end
-
1
;
...
...
am/src/xs/isa/riscv/pmp.c
浏览文件 @
e4957617
...
...
@@ -208,7 +208,8 @@ void init_pmp() {
}
// set PMP to access all memory in S-mode
// asm volatile("csrw pmpaddr8, %0" : : "r"(-1));
asm
volatile
(
"csrw pmpcfg2, %0"
:
:
"r"
(
31
));
// the last pmp pair is used to enable all access (in current case is pmp15)
asm
volatile
(
"csrw pmpcfg2, %0"
:
:
"r"
((
long
)
31
<<
(
8
*
7
)));
asm
volatile
(
"sfence.vma"
);
}
...
...
tests/amtest/src/main.c
浏览文件 @
e4957617
...
...
@@ -33,6 +33,7 @@ int main(const char *args) {
CASE
(
'p'
,
vm_test
,
CTE
(
vm_handler
),
VME
(
simple_pgalloc
,
simple_pgfree
));
CASE
(
'c'
,
pmp_test
,
CTE
(
simple_trap
));
CASE
(
's'
,
sv39_test
,
IOE
,
CTE
(
simple_trap
));
CASE
(
'f'
,
sv39_hp_atom_test
,
IOE
,
CTE
(
simple_trap
));
CASE
(
'b'
,
cache_test
);
case
'H'
:
default:
...
...
tests/amtest/src/tests/pmp.c
浏览文件 @
e4957617
...
...
@@ -7,50 +7,191 @@
* You may find related initialzation code in __am_init_cte64()
*/
#define PMP_1
#define EXCEPTION_LOAD_ACCESS_FAULT 5
#define EXCEPTION_STORE_ACCESS_FAULT 7
uint64_t
access_fault_to_be_reported
=
0
;
inline
int
inst_is_compressed
(
uint64_t
addr
){
uint8_t
byte
=
*
(
uint8_t
*
)
addr
;
return
(
byte
&
0x3
)
!=
0x3
;
}
volatile
uint64_t
pmp_store_access_fault_to_be_reported
=
0
;
volatile
uint64_t
pmp_store_access_fault_reported
=
0
;
volatile
uint64_t
pmp_load_access_fault_to_be_reported
=
0
;
volatile
uint64_t
pmp_load_access_fault_reported
=
0
;
volatile
int
result_blackhole
=
0
;
void
reset_result_flags
()
{
pmp_store_access_fault_to_be_reported
=
0
;
pmp_store_access_fault_reported
=
0
;
pmp_load_access_fault_to_be_reported
=
0
;
pmp_load_access_fault_reported
=
0
;
}
_Context
*
store_access_fault_handler
(
_Event
*
ev
,
_Context
*
c
)
{
printf
(
"store access fault triggered
\n
"
);
if
(
access_fault_to_be_reported
)
{
_halt
(
0
);
void
result_check
()
{
assert
(
!
(
pmp_store_access_fault_to_be_reported
&&
pmp_load_access_fault_to_be_reported
));
if
(
pmp_store_access_fault_to_be_reported
)
{
if
(
!
pmp_store_access_fault_reported
||
pmp_load_access_fault_reported
)
{
printf
(
"pmp_store_access_fault_reported %x, pmp_load_access_fault_reported %x
\n
"
,
pmp_store_access_fault_reported
,
pmp_load_access_fault_reported
);
_halt
(
1
);
}
}
else
if
(
pmp_load_access_fault_to_be_reported
)
{
if
(
!
pmp_load_access_fault_reported
||
pmp_store_access_fault_reported
)
{
printf
(
"pmp_store_access_fault_reported %x, pmp_load_access_fault_reported %x
\n
"
,
pmp_store_access_fault_reported
,
pmp_load_access_fault_reported
);
_halt
(
1
);
}
}
else
{
_halt
(
1
);
// something went wrong
if
(
pmp_load_access_fault_reported
||
pmp_store_access_fault_reported
)
{
printf
(
"pmp_store_access_fault_reported %x, pmp_load_access_fault_reported %x
\n
"
,
pmp_store_access_fault_reported
,
pmp_load_access_fault_reported
);
_halt
(
1
);
}
}
// result check passed, reset flags
pmp_store_access_fault_to_be_reported
=
0
;
pmp_store_access_fault_reported
=
0
;
pmp_load_access_fault_to_be_reported
=
0
;
pmp_load_access_fault_reported
=
0
;
}
_Context
*
pmp_store_access_fault_handler
(
_Event
*
ev
,
_Context
*
c
)
{
printf
(
"store access fault triggered, sepc %lx
\n
"
,
c
->
sepc
);
pmp_store_access_fault_reported
=
1
;
// skip the inst that triggered the exception
c
->
sepc
=
inst_is_compressed
(
c
->
sepc
)
?
c
->
sepc
+
2
:
c
->
sepc
+
4
;
// printf("goto %x\n", c->sepc);
return
c
;
}
_Context
*
pmp_load_access_fault_handler
(
_Event
*
ev
,
_Context
*
c
)
{
printf
(
"load access fault triggered, sepc %lx
\n
"
,
c
->
sepc
);
pmp_load_access_fault_reported
=
1
;
// skip the inst that triggered the exception
c
->
sepc
=
inst_is_compressed
(
c
->
sepc
)
?
c
->
sepc
+
2
:
c
->
sepc
+
4
;
// printf("goto %x\n", c->sepc);
return
c
;
}
void
pmp_test
()
{
irq_handler_reg
(
EXCEPTION_STORE_ACCESS_FAULT
,
&
store_access_fault_handler
);
irq_handler_reg
(
EXCEPTION_STORE_ACCESS_FAULT
,
&
pmp_store_access_fault_handler
);
irq_handler_reg
(
EXCEPTION_LOAD_ACCESS_FAULT
,
&
pmp_load_access_fault_handler
);
printf
(
"start pmp test
\n
"
);
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS)
#ifdef PMP_1
access_fault_to_be_reported
=
1
;
// Case: store to address protected by pmp
pmp_store_
access_fault_to_be_reported
=
1
;
volatile
int
*
a
=
(
int
*
)(
0x90000040UL
);
*
a
=
1
;
// should trigger a fault
#endif
#ifdef PMP_2
access_fault_to_be_reported
=
0
;
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: store to normal cacheable address
int
*
b
=
(
int
*
)(
0xa0000000UL
);
*
b
=
1
;
// should not trigger a fault
#endif
#ifdef PMP_3
access_fault_to_be_reported
=
1
;
int
*
c
=
(
int
*
)(
0xb00000040UL
);
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: store to address protected by pmp tor
pmp_store_access_fault_to_be_reported
=
1
;
int
*
c
=
(
int
*
)(
0xb0000040UL
);
*
c
=
1
;
// should trigger a fault
#endif
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: load from address protected by pmp
pmp_load_access_fault_to_be_reported
=
1
;
volatile
int
*
d
=
(
int
*
)(
0x90000040UL
);
result_blackhole
=
(
*
d
);
// should trigger a fault
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: load from address protected by pmp tor
pmp_load_access_fault_to_be_reported
=
1
;
volatile
int
*
e
=
(
int
*
)(
0xb0000040UL
);
result_blackhole
=
(
*
e
);
// should trigger a fault
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: store to address protected by pmp (use pmpcfg2)
pmp_store_access_fault_to_be_reported
=
1
;
int
*
f
=
(
int
*
)(
0xb0010000UL
);
*
f
=
1
;
// should trigger a fault
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: lr from address protected by pmp
pmp_load_access_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xb0000040;"
"lr.d s5, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: sc to address protected by pmp
pmp_store_access_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xb0000040;"
"sc.d s5, s5, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: amo to address protected by pmp
pmp_store_access_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xb0000040;"
"amoadd.d s5, s6, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: amo to address protected by pmp (w,!r)
pmp_store_access_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xb0008000;"
"amoadd.d s5, s6, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
// Case: amo to address protected by pmp (!w,r)
pmp_store_access_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xb0004000;"
"amoadd.d s5, s6, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
result_check
();
printf
(
"line %d passed
\n
"
,
__LINE__
);
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
access_fault_to_be_reported
=
0
;
// TODO: update pmp test for southlake
pmp_store_access_fault_to_be_reported
=
0
;
int
*
b
=
(
int
*
)(
0x2030000000UL
);
*
b
=
1
;
// should not trigger a fault
access_fault_to_be_reported
=
1
;
result_check
();
pmp_store_access_fault_to_be_reported
=
1
;
volatile
int
*
a
=
(
int
*
)(
0x2010000040UL
);
*
a
=
1
;
// should trigger a fault
printf
(
"Store access fault not triggered
\n
"
);
_halt
(
1
);
result_check
();
#else
// invalid arch
printf
(
"invalid arch
\n
"
);
...
...
tests/amtest/src/tests/sv39.c
浏览文件 @
e4957617
...
...
@@ -6,6 +6,8 @@
* RISC-V 64 SV39 Virutal Memory test
*/
#define EXCEPTION_LOAD_ACCESS_FAULT 5
#define EXCEPTION_STORE_ACCESS_FAULT 7
#define EXCEPTION_LOAD_PAGE_FAULT 13
#define EXCEPTION_STORE_PAGE_FAULT 15
...
...
@@ -17,29 +19,53 @@ static char *sv39_alloc_base = (char *)(0x2040000000UL);
// invalid arch
#endif
uint64_t
page_fault_to_be_reported
=
0
;
volatile
uint64_t
load_page_fault_to_be_reported
=
0
;
volatile
uint64_t
store_page_fault_to_be_reported
=
0
;
volatile
uint64_t
load_access_fault_to_be_reported
=
0
;
volatile
uint64_t
store_access_fault_to_be_reported
=
0
;
inline
int
inst_is_compressed
(
uint64_t
addr
){
uint8_t
byte
=
*
(
uint8_t
*
)
addr
;
return
(
byte
|
0x3
)
!=
0x3
;
return
(
byte
&
0x3
)
!=
0x3
;
}
_Context
*
store_page_fault_handler
(
_Event
*
ev
,
_Context
*
c
)
{
printf
(
"store page fault triggered
\n
"
);
if
(
!
page_fault_to_be_reported
){
if
(
!
store_
page_fault_to_be_reported
){
_halt
(
1
);
// something went wrong
}
page_fault_to_be_reported
=
0
;
store_
page_fault_to_be_reported
=
0
;
c
->
sepc
=
inst_is_compressed
(
c
->
sepc
)
?
c
->
sepc
+
2
:
c
->
sepc
+
4
;
return
c
;
}
_Context
*
load_page_fault_handler
(
_Event
*
ev
,
_Context
*
c
)
{
printf
(
"load page fault triggered
\n
"
);
if
(
!
page_fault_to_be_reported
){
if
(
!
load_page_fault_to_be_reported
){
_halt
(
1
);
// something went wrong
}
load_page_fault_to_be_reported
=
0
;
c
->
sepc
=
inst_is_compressed
(
c
->
sepc
)
?
c
->
sepc
+
2
:
c
->
sepc
+
4
;
return
c
;
}
_Context
*
load_access_fault_handler
(
_Event
*
ev
,
_Context
*
c
)
{
printf
(
"load access fault triggered
\n
"
);
if
(
!
load_access_fault_to_be_reported
){
_halt
(
1
);
// something went wrong
}
page_fault_to_be_reported
=
0
;
load_access_fault_to_be_reported
=
0
;
c
->
sepc
=
inst_is_compressed
(
c
->
sepc
)
?
c
->
sepc
+
2
:
c
->
sepc
+
4
;
return
c
;
}
_Context
*
store_access_fault_handler
(
_Event
*
ev
,
_Context
*
c
)
{
printf
(
"store access fault triggered
\n
"
);
if
(
!
store_access_fault_to_be_reported
){
_halt
(
1
);
// something went wrong
}
store_access_fault_to_be_reported
=
0
;
c
->
sepc
=
inst_is_compressed
(
c
->
sepc
)
?
c
->
sepc
+
2
:
c
->
sepc
+
4
;
return
c
;
}
...
...
@@ -94,17 +120,144 @@ void sv39_test() {
assert
(
*
r_ptr
==
'a'
);
printf
(
"test sv39 store page fault
\n
"
);
page_fault_to_be_reported
=
1
;
*
fault_ptr
=
'b'
;
// store: not compressed
if
(
page_fault_to_be_reported
){
store_
page_fault_to_be_reported
=
1
;
*
fault_ptr
=
'b'
;
if
(
store_
page_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 load page fault
\n
"
);
page_fault_to_be_reported
=
1
;
load_
page_fault_to_be_reported
=
1
;
*
w_ptr
=
*
fault_ptr
;
if
(
page_fault_to_be_reported
){
if
(
load_
page_fault_to_be_reported
){
_halt
(
1
);
}
_halt
(
0
);
}
/*
* RISC-V 64 SV39 Hugepage + Hugepage Atom Inst test
*/
void
sv39_hp_atom_test
()
{
printf
(
"start sv39 hugepage atom test
\n
"
);
_vme_init
(
sv39_pgalloc
,
sv39_pgfree
);
printf
(
"sv39 setup done
\n
"
);
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS)
_map
(
&
kas
,
(
void
*
)
0x900000000UL
,
(
void
*
)
0x80200000
,
PTE_R
|
PTE_A
|
PTE_D
);
// allocate a metapage, not protected by pmp
_map_rv_hugepage
(
&
kas
,
(
void
*
)
0xa00000000UL
,
(
void
*
)
0x80200000
,
PTE_W
|
PTE_R
|
PTE_A
|
PTE_D
,
1
);
// allocate a metapage, not protected by pmp, without write perm
_map_rv_hugepage
(
&
kas
,
(
void
*
)
0xb00000000UL
,
(
void
*
)
0x80200000
,
PTE_R
|
PTE_A
|
PTE_D
,
1
);
// allocate a metapage, not protected by pmp, without read perm
_map_rv_hugepage
(
&
kas
,
(
void
*
)
0xc00000000UL
,
(
void
*
)
0x80200000
,
PTE_W
|
PTE_A
|
PTE_D
,
1
);
// allocate a metapage, protected by pmp (!rw)
_map_rv_hugepage
(
&
kas
,
(
void
*
)
0xd00000000UL
,
(
void
*
)
0xb0000000
,
PTE_W
|
PTE_R
|
PTE_A
|
PTE_D
,
1
);
char
*
normal_rw_ptr
=
(
char
*
)(
0x900000000UL
);
char
*
hp_rw_ptr
=
(
char
*
)(
0xa00000000UL
);
char
*
hp_r_ptr
=
(
char
*
)(
0xb00000000UL
);
char
*
hp_w_ptr
=
(
char
*
)(
0xc00000000UL
);
char
*
hp_pmp_ptr
=
(
char
*
)(
0xd00000000UL
);
printf
(
"memory map done
\n
"
);
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
// TODO
#else
// invalid arch
_halt
(
1
);
#endif
irq_handler_reg
(
EXCEPTION_STORE_PAGE_FAULT
,
&
store_page_fault_handler
);
irq_handler_reg
(
EXCEPTION_LOAD_PAGE_FAULT
,
&
load_page_fault_handler
);
irq_handler_reg
(
EXCEPTION_STORE_ACCESS_FAULT
,
&
store_access_fault_handler
);
irq_handler_reg
(
EXCEPTION_LOAD_ACCESS_FAULT
,
&
load_access_fault_handler
);
printf
(
"test sv39 hugepage data write
\n
"
);
*
hp_rw_ptr
=
'a'
;
printf
(
"test sv39 hugepage data read
\n
"
);
assert
(
*
hp_rw_ptr
==
'a'
);
printf
(
"test sv39 normalpage data read
\n
"
);
assert
(
*
normal_rw_ptr
==
'a'
);
printf
(
"test sv39 hugepage store page fault
\n
"
);
store_page_fault_to_be_reported
=
1
;
*
hp_r_ptr
=
'b'
;
if
(
store_page_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 hugepage load page fault
\n
"
);
load_page_fault_to_be_reported
=
1
;
*
hp_rw_ptr
=
*
hp_w_ptr
;
if
(
load_page_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 hugepage store access fault
\n
"
);
store_access_fault_to_be_reported
=
1
;
*
hp_pmp_ptr
=
'b'
;
if
(
store_page_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 hugepage load access fault
\n
"
);
load_access_fault_to_be_reported
=
1
;
*
hp_rw_ptr
=
*
hp_pmp_ptr
;
if
(
load_access_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 hugepage atom store page fault
\n
"
);
store_page_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xb00000000;"
"amoadd.d s5, s6, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
if
(
store_page_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 hugepage atom load page fault
\n
"
);
load_page_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xc00000000;"
"lr.d s5, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
if
(
load_page_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 hugepage atom store access fault
\n
"
);
store_access_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xd00000000;"
"amoadd.d s5, s6, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
if
(
store_page_fault_to_be_reported
){
_halt
(
1
);
}
printf
(
"test sv39 hugepage atom load access fault
\n
"
);
load_access_fault_to_be_reported
=
1
;
asm
volatile
(
"li s4, 0xd00000000;"
"lr.d s5, (s4);"
:
:
:
"s4"
,
"s5"
,
"s6"
);
if
(
load_access_fault_to_be_reported
){
_halt
(
1
);
}
_halt
(
0
);
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录