@@ -12,6 +12,24 @@ void state_t::add_csr(reg_t addr, const csr_t_p& csr)
1212#define add_supervisor_csr (addr, csr ) add_const_ext_csr(' S' , addr, csr)
1313#define add_hypervisor_csr (addr, csr ) add_ext_csr(' H' , addr, csr)
1414
15+ void state_t::add_ireg_proxy (processor_t * const proc, sscsrind_reg_csr_t ::sscsrind_reg_csr_t_p ireg)
16+ {
17+ // This assumes xlen is always max_xlen, which is true today (see
18+ // mstatus_csr_t::unlogged_write()):
19+ auto xlen = proc->get_isa ().get_max_xlen ();
20+
21+ const reg_t iprio0_addr = 0x30 ;
22+ for (int i=0 ; i<16 ; i+=2 ) {
23+ csr_t_p iprio = std::make_shared<aia_csr_t >(proc, iprio0_addr + i, 0 , 0 );
24+ if (xlen == 32 ) {
25+ ireg->add_ireg_proxy (iprio0_addr + i, std::make_shared<rv32_low_csr_t >(proc, iprio0_addr + i, iprio));
26+ ireg->add_ireg_proxy (iprio0_addr + i + 1 , std::make_shared<rv32_high_csr_t >(proc, iprio0_addr + i + 1 , iprio));
27+ } else {
28+ ireg->add_ireg_proxy (iprio0_addr + i, iprio);
29+ }
30+ }
31+ }
32+
1533void state_t::csr_init (processor_t * const proc, reg_t max_isa)
1634{
1735 // This assumes xlen is always max_xlen, which is true today (see
@@ -87,8 +105,17 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
87105 }
88106 }
89107 add_const_ext_csr (EXT_SSCOFPMF, CSR_SCOUNTOVF, std::make_shared<scountovf_csr_t >(proc, CSR_SCOUNTOVF));
90- add_csr (CSR_MIE, mie = std::make_shared<mie_csr_t >(proc, CSR_MIE));
91- add_csr (CSR_MIP, mip = std::make_shared<mip_csr_t >(proc, CSR_MIP));
108+ mie = std::make_shared<mie_csr_t >(proc, CSR_MIE);
109+ mip = std::make_shared<mip_csr_t >(proc, CSR_MIP);
110+ if (xlen == 32 && proc->extension_enabled_const (EXT_SMAIA)) {
111+ add_csr (CSR_MIE, std::make_shared<rv32_low_csr_t >(proc, CSR_MIE, mie));
112+ add_csr (CSR_MIEH, std::make_shared<rv32_high_csr_t >(proc, CSR_MIEH, mie));
113+ add_csr (CSR_MIP, std::make_shared<rv32_low_csr_t >(proc, CSR_MIP, mip));
114+ add_csr (CSR_MIPH, std::make_shared<rv32_high_csr_t >(proc, CSR_MIPH, mip));
115+ } else {
116+ add_csr (CSR_MIE, mie);
117+ add_csr (CSR_MIP, mip);
118+ }
92119 auto sip_sie_accr = std::make_shared<generic_int_accessor_t >(
93120 this ,
94121 ~MIP_HS_MASK, // read_mask
@@ -116,21 +143,49 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
116143 1 // shiftamt
117144 );
118145
119- auto nonvirtual_sip = std::make_shared<mip_proxy_csr_t >(proc, CSR_SIP, sip_sie_accr);
146+ nonvirtual_sip = std::make_shared<sip_csr_t >(proc, CSR_SIP, sip_sie_accr);
120147 auto vsip = std::make_shared<mip_proxy_csr_t >(proc, CSR_VSIP, vsip_vsie_accr);
121- add_hypervisor_csr (CSR_VSIP, vsip);
122- add_supervisor_csr (CSR_SIP, std::make_shared<virtualized_csr_t >(proc, nonvirtual_sip, vsip));
148+ auto sip = std::make_shared<virtualized_csr_t >(proc, nonvirtual_sip, vsip);
149+ if (xlen == 32 && proc->extension_enabled_const (EXT_SSAIA)) {
150+ add_hypervisor_csr (CSR_VSIP, std::make_shared<rv32_low_csr_t >(proc, CSR_VSIP, vsip));
151+ add_hypervisor_csr (CSR_VSIPH, std::make_shared<aia_rv32_high_csr_t >(proc, CSR_VSIPH, vsip));
152+ add_supervisor_csr (CSR_SIP, std::make_shared<rv32_low_csr_t >(proc, CSR_SIP, sip));
153+ add_supervisor_csr (CSR_SIPH, std::make_shared<aia_rv32_high_csr_t >(proc, CSR_SIPH, sip));
154+ } else {
155+ add_hypervisor_csr (CSR_VSIP, vsip);
156+ add_supervisor_csr (CSR_SIP, sip);
157+ }
123158 add_hypervisor_csr (CSR_HIP, std::make_shared<mip_proxy_csr_t >(proc, CSR_HIP, hip_hie_accr));
124- add_hypervisor_csr (CSR_HVIP, hvip = std::make_shared<hvip_csr_t >(proc, CSR_HVIP, 0 ));
159+ hvip = std::make_shared<hvip_csr_t >(proc, CSR_HVIP, 0 );
160+ if (xlen == 32 && proc->extension_enabled_const (EXT_SSAIA)) {
161+ add_hypervisor_csr (CSR_HVIP, std::make_shared<rv32_low_csr_t >(proc, CSR_HVIP, hvip));
162+ add_hypervisor_csr (CSR_HVIPH, std::make_shared<aia_rv32_high_csr_t >(proc, CSR_HVIPH, hvip));
163+ } else {
164+ add_hypervisor_csr (CSR_HVIP, hvip);
165+ }
125166
126- auto nonvirtual_sie = std::make_shared<mie_proxy_csr_t >(proc, CSR_SIE, sip_sie_accr);
167+ nonvirtual_sie = std::make_shared<sie_csr_t >(proc, CSR_SIE, sip_sie_accr);
127168 auto vsie = std::make_shared<mie_proxy_csr_t >(proc, CSR_VSIE, vsip_vsie_accr);
128- add_hypervisor_csr (CSR_VSIE, vsie);
129- add_supervisor_csr (CSR_SIE, std::make_shared<virtualized_csr_t >(proc, nonvirtual_sie, vsie));
169+ auto sie = std::make_shared<virtualized_csr_t >(proc, nonvirtual_sie, vsie);
170+ if (xlen == 32 && proc->extension_enabled_const (EXT_SSAIA)) {
171+ add_hypervisor_csr (CSR_VSIE, std::make_shared<rv32_low_csr_t >(proc, CSR_VSIE, vsie));
172+ add_hypervisor_csr (CSR_VSIEH, std::make_shared<aia_rv32_high_csr_t >(proc, CSR_VSIEH, vsie));
173+ add_supervisor_csr (CSR_SIE, std::make_shared<rv32_low_csr_t >(proc, CSR_SIE, sie));
174+ add_supervisor_csr (CSR_SIEH, std::make_shared<aia_rv32_high_csr_t >(proc, CSR_SIEH, sie));
175+ } else {
176+ add_hypervisor_csr (CSR_VSIE, vsie);
177+ add_supervisor_csr (CSR_SIE, sie);
178+ }
130179 add_hypervisor_csr (CSR_HIE, std::make_shared<mie_proxy_csr_t >(proc, CSR_HIE, hip_hie_accr));
131180
132181 add_supervisor_csr (CSR_MEDELEG, medeleg = std::make_shared<medeleg_csr_t >(proc, CSR_MEDELEG));
133- add_supervisor_csr (CSR_MIDELEG, mideleg = std::make_shared<mideleg_csr_t >(proc, CSR_MIDELEG));
182+ mideleg = std::make_shared<mideleg_csr_t >(proc, CSR_MIDELEG);
183+ if (xlen == 32 && proc->extension_enabled_const (EXT_SMAIA)) {
184+ add_supervisor_csr (CSR_MIDELEG, std::make_shared<rv32_low_csr_t >(proc, CSR_MIDELEG, mideleg));
185+ add_supervisor_csr (CSR_MIDELEGH, std::make_shared<aia_rv32_high_csr_t >(proc, CSR_MIDELEGH, mideleg));
186+ } else {
187+ add_supervisor_csr (CSR_MIDELEG, mideleg);
188+ }
134189 const reg_t counteren_mask = (proc->extension_enabled_const (EXT_ZICNTR) ? 0x7UL : 0x0 ) | (proc->extension_enabled_const (EXT_ZIHPM) ? 0xfffffff8ULL : 0x0 );
135190 add_user_csr (CSR_MCOUNTEREN, mcounteren = std::make_shared<masked_csr_t >(proc, CSR_MCOUNTEREN, counteren_mask, 0 ));
136191 add_csr (CSR_MCOUNTINHIBIT, mcountinhibit = std::make_shared<masked_csr_t >(proc, CSR_MCOUNTINHIBIT, counteren_mask & (~MCOUNTEREN_TIME), 0 ));
@@ -162,7 +217,13 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
162217 add_hypervisor_csr (CSR_HSTATUS, hstatus = std::make_shared<hstatus_csr_t >(proc, CSR_HSTATUS));
163218 add_hypervisor_csr (CSR_HGEIE, std::make_shared<const_csr_t >(proc, CSR_HGEIE, 0 ));
164219 add_hypervisor_csr (CSR_HGEIP, std::make_shared<const_csr_t >(proc, CSR_HGEIP, 0 ));
165- add_hypervisor_csr (CSR_HIDELEG, hideleg = std::make_shared<hideleg_csr_t >(proc, CSR_HIDELEG, mideleg));
220+ hideleg = std::make_shared<hideleg_csr_t >(proc, CSR_HIDELEG, mideleg);
221+ if (xlen == 32 && proc->extension_enabled_const (EXT_SSAIA)) {
222+ add_hypervisor_csr (CSR_HIDELEG, std::make_shared<rv32_low_csr_t >(proc, CSR_HIDELEG, hideleg));
223+ add_hypervisor_csr (CSR_HIDELEGH, std::make_shared<aia_rv32_high_csr_t >(proc, CSR_HIDELEGH, hideleg));
224+ } else {
225+ add_hypervisor_csr (CSR_HIDELEG, hideleg);
226+ }
166227 const reg_t hedeleg_mask =
167228 (1 << CAUSE_MISALIGNED_FETCH) |
168229 (1 << CAUSE_FETCH_ACCESS) |
@@ -285,7 +346,7 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
285346 const reg_t sstateen0_mask = (proc->extension_enabled (EXT_ZFINX) ? SSTATEEN0_FCSR : 0 ) |
286347 (proc->extension_enabled (EXT_ZCMT) ? SSTATEEN0_JVT : 0 ) |
287348 SSTATEEN0_CS;
288- const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN;
349+ const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_CSRIND | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN;
289350 const reg_t mstateen0_mask = hstateen0_mask | (proc->extension_enabled (EXT_SSQOSID) ? MSTATEEN0_PRIV114 : 0 );
290351 for (int i = 0 ; i < 4 ; i++) {
291352 const reg_t mstateen_mask = i == 0 ? mstateen0_mask : MSTATEEN_HSTATEEN;
@@ -321,7 +382,7 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
321382 if (proc->extension_enabled_const (EXT_SSTC)) {
322383 stimecmp = std::make_shared<stimecmp_csr_t >(proc, CSR_STIMECMP, MIP_STIP);
323384 vstimecmp = std::make_shared<stimecmp_csr_t >(proc, CSR_VSTIMECMP, MIP_VSTIP);
324- auto virtualized_stimecmp = std::make_shared<virtualized_stimecmp_csr_t >(proc, stimecmp, vstimecmp);
385+ auto virtualized_stimecmp = std::make_shared<virtualized_with_special_permission_csr_t >(proc, stimecmp, vstimecmp);
325386 if (xlen == 32 ) {
326387 add_supervisor_csr (CSR_STIMECMP, std::make_shared<rv32_low_csr_t >(proc, CSR_STIMECMP, virtualized_stimecmp));
327388 add_supervisor_csr (CSR_STIMECMPH, std::make_shared<rv32_high_csr_t >(proc, CSR_STIMECMPH, virtualized_stimecmp));
@@ -348,20 +409,30 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
348409 csr_t_p miselect = std::make_shared<basic_csr_t >(proc, CSR_MISELECT, 0 );
349410 add_csr (CSR_MISELECT, miselect);
350411
351- const reg_t mireg_csrs[] = { CSR_MIREG, CSR_MIREG2, CSR_MIREG3, CSR_MIREG4, CSR_MIREG5, CSR_MIREG6 };
412+ sscsrind_reg_csr_t ::sscsrind_reg_csr_t_p mireg;
413+ add_csr (CSR_MIREG, mireg = std::make_shared<sscsrind_reg_csr_t >(proc, CSR_MIREG, miselect));
414+ add_ireg_proxy (proc, mireg);
415+ const reg_t mireg_csrs[] = { CSR_MIREG2, CSR_MIREG3, CSR_MIREG4, CSR_MIREG5, CSR_MIREG6 };
352416 for (auto csr : mireg_csrs)
353417 add_csr (csr, std::make_shared<sscsrind_reg_csr_t >(proc, csr, miselect));
354418 }
355419
356420 if (proc->extension_enabled_const (EXT_SSCSRIND)) {
357- csr_t_p vsiselect = std::make_shared<basic_csr_t >(proc, CSR_VSISELECT, 0 );
421+ csr_t_p vsiselect = std::make_shared<siselect_csr_t >(proc, CSR_VSISELECT, 0 );
358422 add_hypervisor_csr (CSR_VSISELECT, vsiselect);
359423
360- csr_t_p siselect = std::make_shared<basic_csr_t >(proc, CSR_SISELECT, 0 );
361- add_supervisor_csr (CSR_SISELECT, std::make_shared<virtualized_csr_t >(proc, siselect, vsiselect));
424+ csr_t_p siselect = std::make_shared<siselect_csr_t >(proc, CSR_SISELECT, 0 );
425+ add_supervisor_csr (CSR_SISELECT, std::make_shared<virtualized_with_special_permission_csr_t >(proc, siselect, vsiselect));
362426
363- const reg_t vsireg_csrs[] = { CSR_VSIREG, CSR_VSIREG2, CSR_VSIREG3, CSR_VSIREG4, CSR_VSIREG5, CSR_VSIREG6 };
364- const reg_t sireg_csrs[] = { CSR_SIREG, CSR_SIREG2, CSR_SIREG3, CSR_SIREG4, CSR_SIREG5, CSR_SIREG6 };
427+ auto vsireg = std::make_shared<sscsrind_reg_csr_t >(proc, CSR_VSIREG, vsiselect);
428+ add_hypervisor_csr (CSR_VSIREG, vsireg);
429+
430+ auto sireg = std::make_shared<sscsrind_reg_csr_t >(proc, CSR_SIREG, siselect);
431+ add_ireg_proxy (proc, sireg);
432+ add_supervisor_csr (CSR_SIREG, std::make_shared<virtualized_indirect_csr_t >(proc, sireg, vsireg));
433+
434+ const reg_t vsireg_csrs[] = { CSR_VSIREG2, CSR_VSIREG3, CSR_VSIREG4, CSR_VSIREG5, CSR_VSIREG6 };
435+ const reg_t sireg_csrs[] = { CSR_SIREG2, CSR_SIREG3, CSR_SIREG4, CSR_SIREG5, CSR_SIREG6 };
365436 for (size_t i = 0 ; i < std::size (vsireg_csrs); i++) {
366437 auto vsireg = std::make_shared<sscsrind_reg_csr_t >(proc, vsireg_csrs[i], vsiselect);
367438 add_hypervisor_csr (vsireg_csrs[i], vsireg);
@@ -438,4 +509,44 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
438509
439510 const reg_t srmcfg_mask = SRMCFG_MCID | SRMCFG_RCID;
440511 add_const_ext_csr (EXT_SSQOSID, CSR_SRMCFG, std::make_shared<srmcfg_csr_t >(proc, CSR_SRMCFG, srmcfg_mask, 0 ));
512+
513+ mvien = std::make_shared<masked_csr_t >(proc, CSR_MVIEN, MIP_SEIP | MIP_SSIP, 0 );
514+ mvip = std::make_shared<mvip_csr_t >(proc, CSR_MVIP, 0 );
515+ if (proc->extension_enabled_const (EXT_SMAIA)) {
516+ add_csr (CSR_MTOPI, std::make_shared<mtopi_csr_t >(proc, CSR_MTOPI));
517+ if (xlen == 32 ) {
518+ add_supervisor_csr (CSR_MVIEN, std::make_shared<rv32_low_csr_t >(proc, CSR_MVIEN, mvien));
519+ add_supervisor_csr (CSR_MVIENH, std::make_shared<rv32_high_csr_t >(proc, CSR_MVIENH, mvien));
520+ add_supervisor_csr (CSR_MVIP, std::make_shared<rv32_low_csr_t >(proc, CSR_MVIP, mvip));
521+ add_supervisor_csr (CSR_MVIPH, std::make_shared<rv32_high_csr_t >(proc, CSR_MVIPH, mvip));
522+ } else {
523+ add_supervisor_csr (CSR_MVIEN, mvien);
524+ add_supervisor_csr (CSR_MVIP, mvip);
525+ }
526+ }
527+
528+ hvictl = std::make_shared<aia_csr_t >(proc, CSR_HVICTL, HVICTL_VTI | HVICTL_IID | HVICTL_DPR | HVICTL_IPRIOM | HVICTL_IPRIO, 0 );
529+ vstopi = std::make_shared<vstopi_csr_t >(proc, CSR_VSTOPI);
530+ if (proc->extension_enabled_const (EXT_SSAIA)) { // Included by EXT_SMAIA
531+ csr_t_p nonvirtual_stopi = std::make_shared<nonvirtual_stopi_csr_t >(proc, CSR_STOPI);
532+ add_supervisor_csr (CSR_STOPI, std::make_shared<virtualized_with_special_permission_csr_t >(proc, nonvirtual_stopi, vstopi));
533+ add_supervisor_csr (CSR_STOPEI, std::make_shared<inaccessible_csr_t >(proc, CSR_STOPEI));
534+ auto hvien = std::make_shared<aia_csr_t >(proc, CSR_HVIEN, 0 , 0 );
535+ auto hviprio1 = std::make_shared<aia_csr_t >(proc, CSR_HVIPRIO1, 0 , 0 );
536+ auto hviprio2 = std::make_shared<aia_csr_t >(proc, CSR_HVIPRIO2, 0 , 0 );
537+ if (xlen == 32 ) {
538+ add_hypervisor_csr (CSR_HVIEN, std::make_shared<rv32_low_csr_t >(proc, CSR_HVIEN, hvien));
539+ add_hypervisor_csr (CSR_HVIENH, std::make_shared<rv32_high_csr_t >(proc, CSR_HVIENH, hvien));
540+ add_hypervisor_csr (CSR_HVIPRIO1, std::make_shared<rv32_low_csr_t >(proc, CSR_HVIPRIO1, hviprio1));
541+ add_hypervisor_csr (CSR_HVIPRIO1H, std::make_shared<rv32_high_csr_t >(proc, CSR_HVIPRIO1H, hviprio1));
542+ add_hypervisor_csr (CSR_HVIPRIO2, std::make_shared<rv32_low_csr_t >(proc, CSR_HVIPRIO2, hviprio2));
543+ add_hypervisor_csr (CSR_HVIPRIO2H, std::make_shared<rv32_high_csr_t >(proc, CSR_HVIPRIO2H, hviprio2));
544+ } else {
545+ add_hypervisor_csr (CSR_HVIEN, hvien);
546+ add_hypervisor_csr (CSR_HVIPRIO1, hviprio1);
547+ add_hypervisor_csr (CSR_HVIPRIO2, hviprio2);
548+ }
549+ add_hypervisor_csr (CSR_HVICTL, hvictl);
550+ add_hypervisor_csr (CSR_VSTOPI, vstopi);
551+ }
441552}
0 commit comments