@@ -1227,12 +1227,8 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
1227
1227
#endif
1228
1228
1229
1229
#ifdef TARGET_CHERI
1230
-
1231
1230
// See Capability Control and Status Registers (CCSRs) in CHERI ISA spec
1232
- // The e “enable” bit tells whether capability extensions are enabled or disabled.
1233
- #define CCSR_ENABLE 0x1
1234
- // The d “dirty” bit tells whether a capability register has been written.
1235
- #define CCSR_DIRTY 0x2
1231
+
1236
1232
// We used to report cause and capcause here, but those have moved to xTVAL
1237
1233
1238
1234
static int read_ccsr (CPURISCVState * env , int csrno , target_ulong * val )
@@ -1241,24 +1237,44 @@ static int read_ccsr(CPURISCVState *env, int csrno, target_ulong *val)
1241
1237
// The capability cause has moved to xTVAL so we don't report it here.
1242
1238
RISCVCPU * cpu = env_archcpu (env );
1243
1239
target_ulong ccsr = 0 ;
1240
+
1241
+ // The e “enable” bit tells whether capability extensions are enabled or disabled.
1244
1242
ccsr = set_field (ccsr , CCSR_ENABLE , cpu -> cfg .ext_cheri );
1243
+
1244
+ // The d “dirty” bit tells whether a capability register has been written.
1245
1245
ccsr = set_field (ccsr , CCSR_DIRTY , 1 ); /* Always report dirty */
1246
+
1246
1247
// For backwards compat we also report cap cause and cap index
1247
1248
// However, this is the last value and is not separated by privilege mode!
1248
1249
// TODO: remove when CheriBSD has been updated to read xTVAL
1249
1250
ccsr |= env -> cap_cause << 5 ;
1250
1251
ccsr |= env -> cap_index << 10 ;
1252
+
1253
+ /* Expose state bits (GCLG) only above U mode */
1254
+ if (env -> priv != PRV_U )
1255
+ ccsr |= env -> sccsr ;
1256
+
1251
1257
qemu_log_mask (CPU_LOG_INT , "Reading xCCSR(%#x): %x\n" , csrno , (int )ccsr );
1252
1258
* val = ccsr ;
1253
1259
return 0 ;
1254
1260
}
1255
1261
1256
1262
static int write_ccsr (CPURISCVState * env , int csrno , target_ulong val )
1257
1263
{
1258
- error_report ("Attempting to write " TARGET_FMT_lx
1259
- "to xCCSR(%#x), this is not supported (yet?)." ,
1260
- val , csrno );
1261
- return -1 ;
1264
+ static const target_ulong gclgmask = (CCSR_GCLGS | CCSR_GCLGU );
1265
+
1266
+ /* U mode writes refused */
1267
+ if (env -> priv == PRV_U ) {
1268
+ error_report ("Attempting to write " TARGET_FMT_lx
1269
+ "to xCCSR(%#x), this is not supported (yet?)." ,
1270
+ val , csrno );
1271
+ return -1 ;
1272
+ }
1273
+
1274
+ /* Take the GCLG bits from the store and update state bits */
1275
+ env -> sccsr = set_field (env -> sccsr , gclgmask , get_field (val , gclgmask ));
1276
+
1277
+ return 0 ;
1262
1278
}
1263
1279
1264
1280
static inline bool csr_needs_asr (CPURISCVState * env , int csrno ) {
@@ -1571,8 +1587,9 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
1571
1587
[CSR_MTINST ] = CSR_OP_RW (hmode , mtinst ),
1572
1588
1573
1589
#ifdef TARGET_CHERI
1574
- // CHERI CSRs: For now we alway report the same values and don't allow
1575
- // turning off any of the bits
1590
+ // CHERI CSRs: For now we always report enabled and dirty and don't support
1591
+ // turning off CHERI. The global capability load generation bits in here
1592
+ // can be written by S or higher.
1576
1593
[CSR_UCCSR ] = CSR_OP_FN_RW (umode , read_ccsr , write_ccsr , "uccsr" ),
1577
1594
[CSR_SCCSR ] = CSR_OP_FN_RW (smode , read_ccsr , write_ccsr , "sccsr" ),
1578
1595
[CSR_MCCSR ] = CSR_OP_FN_RW (any , read_ccsr , write_ccsr , "mccsr" ),
0 commit comments