Skip to content

Commit abe6fd2

Browse files
committed
AIA: add mtopei/stopei/vstopei CSRs
1 parent 18211c4 commit abe6fd2

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

riscv/csr_init.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
550550
mvip = std::make_shared<mvip_csr_t>(proc, CSR_MVIP, 0);
551551
if (proc->extension_enabled_const(EXT_SMAIA)) {
552552
add_csr(CSR_MTOPI, std::make_shared<mtopi_csr_t>(proc, CSR_MTOPI));
553+
add_csr(CSR_MTOPEI, std::make_shared<topei_csr_t>(proc, CSR_MTOPEI, proc->imsic->m));
553554
if (xlen == 32) {
554555
add_supervisor_csr(CSR_MVIEN, std::make_shared<rv32_low_csr_t>(proc, CSR_MVIEN, mvien));
555556
add_supervisor_csr(CSR_MVIENH, std::make_shared<rv32_high_csr_t>(proc, CSR_MVIENH, mvien));
@@ -566,7 +567,9 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
566567
if (proc->extension_enabled_const(EXT_SSAIA)) { // Included by EXT_SMAIA
567568
csr_t_p nonvirtual_stopi = std::make_shared<nonvirtual_stopi_csr_t>(proc, CSR_STOPI);
568569
add_supervisor_csr(CSR_STOPI, std::make_shared<virtualized_with_special_permission_csr_t>(proc, nonvirtual_stopi, vstopi));
569-
add_supervisor_csr(CSR_STOPEI, std::make_shared<inaccessible_csr_t>(proc, CSR_STOPEI));
570+
auto vstopei = std::make_shared<vstopei_csr_t>(proc, CSR_VSTOPEI);
571+
auto nonvirtual_stopei = std::make_shared<nonvirtual_stopei_csr_t>(proc, CSR_STOPEI, proc->imsic->s);
572+
add_supervisor_csr(CSR_STOPEI, std::make_shared<virtualized_with_special_permission_csr_t>(proc, nonvirtual_stopei, vstopei));
570573
auto hvien = std::make_shared<aia_csr_t>(proc, CSR_HVIEN, 0, 0);
571574
auto hviprio1 = std::make_shared<aia_csr_t>(proc, CSR_HVIPRIO1, 0, 0);
572575
auto hviprio2 = std::make_shared<aia_csr_t>(proc, CSR_HVIPRIO2, 0, 0);
@@ -584,5 +587,6 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
584587
}
585588
add_hypervisor_csr(CSR_HVICTL, hvictl);
586589
add_hypervisor_csr(CSR_VSTOPI, vstopi);
590+
add_hypervisor_csr(CSR_VSTOPEI, vstopei);
587591
}
588592
}

riscv/csrs.cc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,3 +2368,71 @@ csrmap_t_p aia_ireg_proxy_csr_t::get_csrmap(reg_t vgein) {
23682368
return csrmap;
23692369
return proc->imsic->get_vs_csrmap(vgein ? vgein : get_field(state->hstatus->read(), HSTATUS_VGEIN));
23702370
}
2371+
2372+
topei_csr_t::topei_csr_t(processor_t* const proc, const reg_t addr, imsic_file_t_p const imsic) : csr_t(proc, addr), imsic(imsic) {
2373+
}
2374+
2375+
imsic_file_t_p topei_csr_t::get_imsic() const noexcept {
2376+
// non-virtualized registers have pointers to IMSIC
2377+
if (imsic)
2378+
return imsic;
2379+
2380+
// Virtualized IMSIC depends on hstatus.vgein
2381+
reg_t vgein = get_field(state->hstatus->read(), HSTATUS_VGEIN);
2382+
if (!vgein || !proc->imsic->vgein_valid(vgein))
2383+
return nullptr;
2384+
return proc->imsic->vs[vgein];
2385+
}
2386+
2387+
reg_t topei_csr_t::read() const noexcept {
2388+
imsic_file_t_p p = get_imsic();
2389+
if (!p)
2390+
return 0;
2391+
2392+
reg_t iid = p->topei();
2393+
reg_t v = 0;
2394+
v = set_field(v, IMSIC_TOPI_IPRIO, iid);
2395+
v = set_field(v, IMSIC_TOPI_IID, iid);
2396+
return v;
2397+
}
2398+
2399+
bool topei_csr_t::unlogged_write(const reg_t val) noexcept {
2400+
imsic_file_t_p p = get_imsic();
2401+
if (!p)
2402+
return false;
2403+
p->claimei(p->topei());
2404+
return true;
2405+
}
2406+
2407+
void nonvirtual_stopei_csr_t::verify_permissions(insn_t insn, bool write) const {
2408+
if (proc->extension_enabled(EXT_SMSTATEEN)) {
2409+
if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_IMSIC))
2410+
throw trap_illegal_instruction(insn.bits());
2411+
2412+
if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_IMSIC))
2413+
throw trap_virtual_instruction(insn.bits());
2414+
}
2415+
2416+
csr_t::verify_permissions(insn, write);
2417+
}
2418+
2419+
void vstopei_csr_t::verify_permissions(insn_t insn, bool write) const {
2420+
if (proc->extension_enabled(EXT_SMSTATEEN)) {
2421+
if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_IMSIC))
2422+
throw trap_illegal_instruction(insn.bits());
2423+
2424+
if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_IMSIC))
2425+
throw trap_virtual_instruction(insn.bits());
2426+
}
2427+
2428+
csr_t::verify_permissions(insn, write);
2429+
2430+
// VGEIN must be valid
2431+
reg_t vgein = get_field(state->hstatus->read(), HSTATUS_VGEIN);
2432+
if (!vgein || !proc->imsic->vgein_valid(vgein)) {
2433+
if (state->v)
2434+
throw trap_virtual_instruction(insn.bits());
2435+
else
2436+
throw trap_illegal_instruction(insn.bits());
2437+
}
2438+
}

riscv/csrs.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,4 +1028,28 @@ class aia_ireg_proxy_csr_t: public csr_t {
10281028
bool vs;
10291029
csrmap_t_p csrmap;
10301030
};
1031+
1032+
class imsic_file_t;
1033+
typedef std::shared_ptr<imsic_file_t> imsic_file_t_p;
1034+
class topei_csr_t: public csr_t {
1035+
public:
1036+
topei_csr_t(processor_t* const proc, const reg_t addr, imsic_file_t_p const imsic);
1037+
virtual reg_t read() const noexcept override;
1038+
protected:
1039+
virtual bool unlogged_write(const reg_t val) noexcept override;
1040+
imsic_file_t_p get_imsic() const noexcept;
1041+
imsic_file_t_p const imsic;
1042+
};
1043+
1044+
class nonvirtual_stopei_csr_t: public topei_csr_t {
1045+
public:
1046+
nonvirtual_stopei_csr_t(processor_t* const proc, const reg_t addr, imsic_file_t_p const imsic) : topei_csr_t(proc, addr, imsic) {}
1047+
virtual void verify_permissions(insn_t insn, bool write) const override;
1048+
};
1049+
1050+
class vstopei_csr_t: public topei_csr_t {
1051+
public:
1052+
vstopei_csr_t(processor_t* const proc, const reg_t addr) : topei_csr_t(proc, addr, nullptr) {}
1053+
virtual void verify_permissions(insn_t insn, bool write) const override;
1054+
};
10311055
#endif

0 commit comments

Comments
 (0)