11
11
/* CSR access control */
12
12
13
13
function csrAccess (csr : csreg ) -> csrRW = csr [11 .. 10 ]
14
- function csrPriv (csr : csreg ) -> priv_level = csr [9 .. 8 ]
14
+ function csrPriv (csr : csreg ) -> nom_priv_bits = csr [9 .. 8 ]
15
15
16
16
// Check that the CSR access is made with sufficient privilege.
17
17
function check_CSR_priv (csr : csreg , p : Privilege ) -> bool =
@@ -21,15 +21,19 @@ function check_CSR_priv(csr : csreg, p : Privilege) -> bool =
21
21
function check_CSR_access (csr : csreg , isWrite : bool ) -> bool =
22
22
not (isWrite & (csrAccess (csr ) == 0b11 ))
23
23
24
+ // TODO: check VS/VU-mode if hypervisor enabled
24
25
function check_TVM_SATP (csr : csreg , p : Privilege ) -> bool =
25
26
not (csr == 0x180 & p == Supervisor & mstatus [TVM ] == 0b1 )
26
27
27
28
// There are several features that are controlled by machine/supervisor enable
28
29
// bits (m/senvcfg, m/scounteren, etc.). This abstracts that logic.
30
+ // TODO: check hcounteren if hypervisor enabled
29
31
function feature_enabled_for_priv (p : Privilege , machine_enable_bit : bit , supervisor_enable_bit : bit ) -> bool = match p {
30
32
Machine => true ,
31
33
Supervisor => machine_enable_bit == bitone ,
32
34
User => machine_enable_bit == bitone & (not (currentlyEnabled (Ext_S )) | supervisor_enable_bit == bitone ),
35
+ VirtualUser => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
36
+ VirtualSupervisor => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
33
37
}
34
38
35
39
// Return true if the counter is enabled OR the CSR is not a counter.
@@ -46,8 +50,13 @@ function check_Counteren(csr : csreg, p : Privilege) -> bool = {
46
50
function check_Stimecmp (csr : csreg , p : Privilege ) -> bool = {
47
51
// Check if it is not stimecmp.
48
52
if csr != 0x14D & csr != 0x15D then return true ;
49
-
50
- p == Machine | (p == Supervisor & mcounteren [TM ] == 0b1 & menvcfg [STCE ] == 0b1 )
53
+ match p {
54
+ Machine => true ,
55
+ Supervisor => mcounteren [TM ] == 0b1 & menvcfg [STCE ] == 0b1 ,
56
+ User => false ,
57
+ VirtualUser => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
58
+ VirtualSupervisor => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
59
+ }
51
60
}
52
61
53
62
/* Seed may only be accessed if we are doing a write, and access has been
@@ -64,6 +73,8 @@ function check_seed_CSR (csr : csreg, p : Privilege, isWrite : bool) -> bool = {
64
73
Machine => true ,
65
74
Supervisor => false , /* TODO: base this on mseccfg */
66
75
User => false , /* TODO: base this on mseccfg */
76
+ VirtualUser => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
77
+ VirtualSupervisor => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
67
78
}
68
79
}
69
80
}
@@ -105,6 +116,7 @@ val valid_reservation = pure {interpreter: "Platform.valid_reservation", c: "val
105
116
function exception_delegatee (e : ExceptionType , p : Privilege ) -> Privilege = {
106
117
let idx = num_of_ExceptionType (e );
107
118
let super = bit_to_bool (medeleg . bits [idx ]);
119
+ // TODO: check VS/VU-mode if hypervisor extension enabled
108
120
let deleg = if currentlyEnabled (Ext_S ) & super then Supervisor else Machine ;
109
121
/* We cannot transition to a less-privileged mode. */
110
122
if privLevel_to_bits (deleg ) <_u privLevel_to_bits (p )
@@ -133,6 +145,7 @@ function findPendingInterrupt(ip : xlenbits) -> option(InterruptType) = {
133
145
*
134
146
* This is used when the hart is in the Active state.
135
147
*/
148
+ // TODO: check hip/hie if hypervisor enabled.
136
149
function getPendingSet (priv : Privilege ) -> option ((xlenbits , Privilege )) = {
137
150
// mideleg can only be non-zero if we support Supervisor mode.
138
151
assert (currentlyEnabled (Ext_S ) | mideleg . bits == zeros ());
@@ -216,6 +229,8 @@ function track_trap(p : Privilege) -> unit = {
216
229
csr_write_callback ("sepc" , sepc );
217
230
},
218
231
User => internal_error (__FILE__, __LINE__, "Invalid privilege level" ),
232
+ VirtualUser => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
233
+ VirtualSupervisor => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
219
234
};
220
235
}
221
236
@@ -230,54 +245,60 @@ function trap_handler(del_priv : Privilege, intr : bool, c : exc_code, pc : xlen
230
245
231
246
match (del_priv ) {
232
247
Machine => {
233
- mcause [IsInterrupt ] = bool_to_bits (intr );
234
- mcause [Cause ] = zero_extend (c );
248
+ mcause [IsInterrupt ] = bool_to_bits (intr );
249
+ mcause [Cause ] = zero_extend (c );
235
250
236
- mstatus [MPIE ] = mstatus [MIE ];
237
- mstatus [MIE ] = 0b0 ;
238
- mstatus [MPP ] = privLevel_to_bits (cur_privilege );
239
- mtval = tval (info );
240
- mepc = pc ;
251
+ mstatus [MPIE ] = mstatus [MIE ];
252
+ mstatus [MIE ] = 0b0 ;
253
+ mstatus [MPP ] = privLevel_to_bits (cur_privilege );
254
+ mtval = tval (info );
255
+ mepc = pc ;
241
256
242
- cur_privilege = del_priv ;
257
+ cur_privilege = del_priv ;
243
258
244
- handle_trap_extension (del_priv , pc , ext );
259
+ handle_trap_extension (del_priv , pc , ext );
245
260
246
- track_trap (del_priv );
261
+ track_trap (del_priv );
247
262
248
- prepare_trap_vector (del_priv , mcause )
263
+ prepare_trap_vector (del_priv , mcause )
249
264
},
250
265
Supervisor => {
251
- assert (currentlyEnabled (Ext_S ), "no supervisor mode present for delegation" );
266
+ assert (currentlyEnabled (Ext_S ), "no supervisor mode present for delegation" );
252
267
253
- scause [IsInterrupt ] = bool_to_bits (intr );
254
- scause [Cause ] = zero_extend (c );
268
+ scause [IsInterrupt ] = bool_to_bits (intr );
269
+ scause [Cause ] = zero_extend (c );
255
270
256
- mstatus [SPIE ] = mstatus [SIE ];
257
- mstatus [SIE ] = 0b0 ;
258
- mstatus [SPP ] = match cur_privilege {
259
- User => 0b0 ,
260
- Supervisor => 0b1 ,
261
- Machine => internal_error (__FILE__, __LINE__, "invalid privilege for s-mode trap" )
262
- };
263
- stval = tval (info );
264
- sepc = pc ;
271
+ mstatus [SPIE ] = mstatus [SIE ];
272
+ mstatus [SIE ] = 0b0 ;
273
+ mstatus [SPP ] = match cur_privilege {
274
+ User => 0b0 ,
275
+ Supervisor => 0b1 ,
276
+ Machine => internal_error (__FILE__, __LINE__, "invalid privilege for s-mode trap" ),
277
+ VirtualUser => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
278
+ VirtualSupervisor => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
279
+ };
280
+ stval = tval (info );
281
+ sepc = pc ;
265
282
266
- cur_privilege = del_priv ;
283
+ cur_privilege = del_priv ;
267
284
268
- handle_trap_extension (del_priv , pc , ext );
285
+ handle_trap_extension (del_priv , pc , ext );
269
286
270
- track_trap (del_priv );
287
+ track_trap (del_priv );
271
288
272
- prepare_trap_vector (del_priv , scause )
289
+ prepare_trap_vector (del_priv , scause )
273
290
},
274
291
User => internal_error (__FILE__, __LINE__, "Invalid privilege level" ),
292
+ VirtualUser => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
293
+ VirtualSupervisor => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
275
294
};
276
295
}
277
296
278
297
function exception_handler (cur_priv : Privilege , ctl : ctl_result ,
279
298
pc : xlenbits ) -> xlenbits = {
280
299
match (cur_priv , ctl ) {
300
+ (VirtualUser , _ ) => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
301
+ (VirtualSupervisor , _ ) => internal_error (__FILE__, __LINE__, "Hypervisor extension not supported" ),
281
302
(_, CTL_TRAP (e )) => {
282
303
let del_priv = exception_delegatee (e . trap , cur_priv );
283
304
if get_config_print_platform ()
@@ -289,7 +310,7 @@ function exception_handler(cur_priv : Privilege, ctl : ctl_result,
289
310
let prev_priv = cur_privilege ;
290
311
mstatus [MIE ] = mstatus [MPIE ];
291
312
mstatus [MPIE ] = 0b1 ;
292
- cur_privilege = privLevel_of_bits (mstatus [MPP ]);
313
+ cur_privilege = privLevel_of_bits (mstatus [MPP ], 0b0 ); // TODO: use mstatus[MPV] if hypervisor enabled
293
314
mstatus [MPP ] = privLevel_to_bits (if currentlyEnabled (Ext_U ) then User else Machine );
294
315
if cur_privilege != Machine
295
316
then mstatus [MPRV ] = 0b0 ;
0 commit comments