@@ -206,6 +206,50 @@ static target_ulong mtvec_stvec_write_handler(target_ulong val_to_write, char* r
206
206
return new_value ;
207
207
}
208
208
209
+ static target_ulong mnxti_read_handler (target_ulong src )
210
+ {
211
+ uint32_t clic_level = env -> clic_interrupt_level ;
212
+ if (env -> clic_interrupt_pending != EXCP_NONE
213
+ && env -> clic_interrupt_priv == PRV_M
214
+ && clic_level > get_field (env -> mcause , MCAUSE_MPIL )
215
+ && clic_level > get_field (env -> mintthresh , MINTTHRESH_TH )
216
+ && !env -> clic_interrupt_vectored
217
+ ) {
218
+ if (src ) {
219
+ csr_write_helper (env , set_field (env -> mintstatus , MINTSTATUS_MIL , clic_level ), CSR_MINTSTATUS );
220
+ target_ulong mc = env -> mcause ;
221
+ mc = set_field (mc , MCAUSE_EXCCODE , env -> clic_interrupt_pending );
222
+ mc |= MCAUSE_INTERRUPT ;
223
+ csr_write_helper (env , mc , CSR_MCAUSE );
224
+ tlib_clic_clear_edge_interrupt ();
225
+ }
226
+ return env -> mtvt + env -> clic_interrupt_pending * sizeof (target_ulong );
227
+ }
228
+ return 0 ;
229
+ }
230
+
231
+ static target_ulong snxti_read_handler (target_ulong src )
232
+ {
233
+ uint32_t clic_level = env -> clic_interrupt_level ;
234
+ if (env -> clic_interrupt_pending != EXCP_NONE
235
+ && env -> clic_interrupt_priv == PRV_S
236
+ && clic_level > get_field (env -> scause , SCAUSE_SPIL )
237
+ && clic_level > get_field (env -> sintthresh , SINTTHRESH_TH )
238
+ && !env -> clic_interrupt_vectored
239
+ ) {
240
+ if (src ) {
241
+ csr_write_helper (env , set_field (env -> mintstatus , MINTSTATUS_SIL , clic_level ), CSR_MINTSTATUS );
242
+ target_ulong sc = env -> scause ;
243
+ sc = set_field (sc , SCAUSE_EXCCODE , env -> clic_interrupt_pending );
244
+ sc |= SCAUSE_INTERRUPT ;
245
+ csr_write_helper (env , sc , CSR_SCAUSE );
246
+ tlib_clic_clear_edge_interrupt ();
247
+ }
248
+ return env -> stvt + env -> clic_interrupt_pending * sizeof (target_ulong );
249
+ }
250
+ return 0 ;
251
+ }
252
+
209
253
static inline void warn_nonexistent_csr_read (const int no )
210
254
{
211
255
tlib_printf (LOG_LEVEL_WARNING , "Reading from CSR #%d that is not implemented." , no );
@@ -910,6 +954,25 @@ target_ulong helper_csrrw(CPUState *env, target_ulong src, target_ulong csr)
910
954
target_ulong helper_csrrs (CPUState * env , target_ulong src , target_ulong csr , target_ulong rs1_pass )
911
955
{
912
956
validate_csr (env , csr , rs1_pass != 0 );
957
+
958
+ /* We implement these CSRs explicitly here because the value used in the RMW (mstatus) is different
959
+ from the result. */
960
+ if (csr == CSR_MNXTI ) {
961
+ src &= 0x1f ;
962
+ target_ulong ms = env -> mstatus ;
963
+ ms |= src ;
964
+ csr_write_helper (env , ms , CSR_MSTATUS );
965
+
966
+ return mnxti_read_handler (src );
967
+ } else if (csr == CSR_SNXTI ) {
968
+ src &= 0x1f ;
969
+ target_ulong ss = env -> mstatus ;
970
+ ss |= src ;
971
+ csr_write_helper (env , ss , CSR_SSTATUS );
972
+
973
+ return snxti_read_handler (src );
974
+ }
975
+
913
976
uint64_t csr_backup = csr_read_helper (env , csr );
914
977
if (rs1_pass != 0 ) {
915
978
csr_write_helper (env , src | csr_backup , csr );
@@ -920,6 +983,23 @@ target_ulong helper_csrrs(CPUState *env, target_ulong src, target_ulong csr, tar
920
983
target_ulong helper_csrrc (CPUState * env , target_ulong src , target_ulong csr , target_ulong rs1_pass )
921
984
{
922
985
validate_csr (env , csr , rs1_pass != 0 );
986
+
987
+ if (csr == CSR_MNXTI ) {
988
+ src &= 0x1f ;
989
+ target_ulong ms = env -> mstatus ;
990
+ ms &= ~src ;
991
+ csr_write_helper (env , ms , CSR_MSTATUS );
992
+
993
+ return mnxti_read_handler (src );
994
+ } else if (csr == CSR_SNXTI ) {
995
+ src &= 0x1f ;
996
+ target_ulong ss = env -> mstatus ;
997
+ ss &= ~src ;
998
+ csr_write_helper (env , ss , CSR_SSTATUS );
999
+
1000
+ return snxti_read_handler (src );
1001
+ }
1002
+
923
1003
uint64_t csr_backup = csr_read_helper (env , csr );
924
1004
if (rs1_pass != 0 ) {
925
1005
csr_write_helper (env , (~src ) & csr_backup , csr );
0 commit comments