1
+ // -----------
2
+ // Copyright (c) 2020. RISC-V International. All rights reserved.
3
+ // SPDX-License-Identifier: BSD-3-Clause
4
+ // -----------
5
+ //
6
+ // This test belongs to the test plan for RISC-V Privilege Arch Compliance developed by 10xEngineers
7
+ // which can be found here: https://docs.google.com/spreadsheets/d/1p13gic7BD6aq7n_dHrqti4QmlGpxY7FkF17RVbG4DC0/edit?usp=sharing
8
+ //
9
+ // This assembly file tests access of pmp registers in M, S, and U mode.
10
+ // pmp csrs are accessable only in M-mode so it should trap in S, and U mode.
11
+ //
12
+ /* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf)
13
+
14
+ // Details are given in /coverage/rv32i_priv.cgf
15
+ */
16
+ //
17
+ #define rvtest_strap_routine
18
+ #include "model_test.h"
19
+ #include "arch_test.h"
20
+ RVTEST_ISA("RV32I_Zicsr" )
21
+ # Test code region
22
+ .section .text .init
23
+ .globl rvtest_entry_point
24
+ rvtest_entry_point:
25
+ RVMODEL_BOOT
26
+ RVTEST_CODE_BEGIN
27
+ #ifdef TEST_CASE_1
28
+ RVTEST_CASE(1 ,"//check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; def TEST_CASE_1=True" ,PMP_access_permission)
29
+ RVTEST_SIGBASE( x13,signature_x13_1)
30
+ .option nopic
31
+ .attribute unaligned_access, 0
32
+ .attribute stack_align, 16
33
+ .align 2
34
+ main:
35
+ #define PMPCFG0 0x3A0 // Address of pmpcfg0 (HAS BEEN USED WHILE ITERATING THE LOOP)
36
+ #define PMPADDR0 0x3B0 // Address of pmpaddr0 (HAS BEEN USED WHILE ITERATING THE LOOP)
37
+ main:
38
+ //////////////////////// INITIAL VALUES ////////////////////////////////
39
+ LI(a5, -1 ) // SEtting up All locked bits (including everyother non-zero bit, which is redundent for this test)
40
+ LI(x5, 100 ) // A rondom number, to check if pmp regs get update after lock bit enable
41
+ // Loop to SET ALL pmpcfg REGs to zero
42
+ .set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
43
+ .rept 4 // START OF LOOP
44
+ csrc pmpcfgi , a5 // Set all pmpcfg regs to zero (initial value)
45
+ .set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
46
+ .endr // END OF LOOP BODY
47
+ // Loop to SET ALL pmpaddr REGs to zero
48
+ // Loop to SET ALL pmpaddr REGs to zero
49
+ .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0
50
+ .rept 16 // START OF LOOP
51
+ csrc pmpaddri, a5 // Set all pmpaddr regs to zero (initial value)
52
+ .set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
53
+ .endr // END OF LOOP BODY
54
+ .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0
55
+ .rept 16 // START OF LOOP
56
+ csrs pmpaddri, a5 // Set all pmpaddr regs to zero (initial value)
57
+ .set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
58
+ .endr // END OF LOOP BODY
59
+ //////////////// VERIFICATION /////////////////////////////////////////
60
+ // READING pmpaddr in M-mode /////////////////////////////////////////
61
+ .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0
62
+ .rept 16 // START OF LOOP
63
+ csrr a4, pmpaddri // READING pmpaddri (i is from 0-15)
64
+ nop // Added nop in case of trap
65
+ RVTEST_SIGUPD(x13,a4) // Storing into signature file
66
+ .set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
67
+ .endr // END OF LOOP BODY
68
+ // WRITING pmpcfg registers //////////////////////////////////////////
69
+ // Write in M-mode will be valid, Write in other modes will cause trap
70
+ LI(a5, PMP_R| PMP_W | PMP_X | PMP_TOR) // LOCKED BIT IS NOT SET
71
+ // Loop to Write ALL pmpcfg regs
72
+ .set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
73
+ .rept 4 // START OF LOOP
74
+ csrw pmpcfgi, a5 // Write pmpcfgi
75
+ nop // Added nop in case of trap
76
+ .set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
77
+ .endr // END OF LOOP BODY
78
+ //////////////// VERIFICATION /////////////////////////////////////////
79
+ // READING pmpcfg in M-mode /////////////////////////////////////////
80
+ // Loop to verify the contents of pmpcfg regs
81
+ .set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
82
+ .rept 4 // START OF LOOP
83
+ csrr a4, pmpcfg0 // Read pmpcfg0
84
+ nop // Added nop in case of trap
85
+ RVTEST_SIGUPD(x13,a4)
86
+ .set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
87
+ .endr // END OF LOOP BODY
88
+ /////////////////// Switch to S-mode ////////////////////////////////////////////
89
+ csrw satp, zero // Disable address translation.
90
+ LI(t2, -1 )
91
+ csrw pmpaddr0, t2 // Updated pmpaddr0 to define PMP region consisting
92
+ // of whole physical memory
93
+ csrr t0, pmpaddr0 // Verify its value by reading back
94
+ nop // Added nop in case of trap
95
+ RVTEST_SIGUPD(x13,t0)
96
+ nop // Added nop in case of trap
97
+ LI(a5, PMP_L| PMP_R| PMP_W | PMP_X | PMP_TOR) // LOCKED BIT IS SET
98
+ csrw pmpcfg0, a5
99
+
100
+ RVTEST_GOTO_LOWER_MODE Smode // GO into S mode
101
+ // REPEATING THE SAME TEST //////////////////////////////////////////
102
+ // IN Smode now
103
+ /////////////////// TEST 01 ////////////////////////////////////////////
104
+ // WRITING pmpaddr registers //////////////////////////////////////////
105
+ // Write in M-mode will be valid, Write in other modes will cause trap
106
+ csrw pmpaddr0, x2 // Write pmpaddr0 in S mode (TRAP)
107
+ nop // Added nop in case of trap
108
+ // READING pmpaddr in S-mode /////////////////////////////////////////
109
+ csrr a4, pmpaddr0 // Reading pmpaddr0 in S mode (TRAP)
110
+ nop // Added nop in case of trap
111
+ /////////////////// Switch back to M-mode ////////////////////////////////////////////
112
+ RVTEST_GOTO_MMODE
113
+ csrr a4, mstatus // VERIFICATION of M-mode
114
+ nop // Added nop in case of trap
115
+ RVTEST_SIGUPD(x13,a4)
116
+ /////////////////// Switch to U-mode ////////////////////////////////////////////
117
+ csrw satp, zero // Disable address translation.
118
+ LI(t2, -1 )
119
+ csrw pmpaddr0, t2 // Updated pmpaddr0 to define PMP region consisting
120
+ // of whole physical memory
121
+ csrr t0, pmpaddr0 // Verify its value by reading back
122
+ nop // Added nop in case of trap
123
+ RVTEST_SIGUPD(x13,t0)
124
+ nop // Added nop in case of trap
125
+ LI(a5, PMP_L| PMP_R| PMP_W | PMP_X | PMP_TOR) // LOCKED BIT IS SET
126
+ csrw pmpcfg0, a5
127
+ // These steps are repeated and can be removed but it will make sure that you will switch mode
128
+ // with full access on physical memory
129
+ RVTEST_GOTO_LOWER_MODE Umode
130
+ // REPEATING THE SAME TEST //////////////////////////////////////////
131
+ // IN U-mode now
132
+ /////////////////// TEST 01 ////////////////////////////////////////////
133
+ // WRITING pmpaddr registers //////////////////////////////////////////
134
+ // Write in M-mode will be valid, Write in other modes will cause trap
135
+ csrw pmpaddr0, x2 // Write pmpaddr0 in u mode (TRAP)
136
+ nop // Added nop in case of trap
137
+ //////////////// VERIFICATION /////////////////////////////////////////
138
+ // READING pmpaddr in S-mode /////////////////////////////////////////
139
+ csrr a4, pmpaddr0 // Reading pmpaddr0 in U mode (TRAP)
140
+ nop // Added nop in case of trap
141
+
142
+ #endif
143
+
144
+ # ---------------------------------------------------------------------------------------------
145
+ # HALT
146
+ RVTEST_CODE_END
147
+ RVMODEL_HALT
148
+
149
+ RVTEST_DATA_BEGIN
150
+ .align 4
151
+
152
+ rvtest_data:
153
+ .word 0xbabecafe
154
+ .word 0xbabecafe
155
+ .word 0xbabecafe
156
+ .word 0xbabecafe
157
+ RVTEST_DATA_END
158
+
159
+
160
+ RVMODEL_DATA_BEGIN
161
+ rvtest_sig_begin:
162
+ sig_begin_canary:
163
+ CANARY;
164
+ signature_x13_1:
165
+ .fill 32*(XLEN/32 ),4 ,0xdeadbeef
166
+
167
+ #ifdef rvtest_mtrap_routine
168
+
169
+ tsig_begin_canary:
170
+ CANARY;
171
+ mtrap_sigptr:
172
+ .fill 64*(XLEN/32 ),4 ,0xdeadbeef
173
+ tsig_end_canary:
174
+ CANARY;
175
+
176
+ #endif
177
+
178
+ #ifdef rvtest_gpr_save
179
+
180
+ gpr_save:
181
+ .fill 32*(XLEN/32 ),4 ,0xdeadbeef
182
+
183
+ #endif
184
+
185
+ sig_end_canary:
186
+ CANARY;
187
+ rvtest_sig_end:
188
+ RVMODEL_DATA_END
0 commit comments