Skip to content

Commit f21722b

Browse files
committed
AIA: add mtopei/stopei/vstopei CSRs
1 parent 9ec7553 commit f21722b

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
@@ -551,6 +551,7 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
551551
mvip = std::make_shared<mvip_csr_t>(proc, CSR_MVIP, 0);
552552
if (proc->extension_enabled_const(EXT_SMAIA)) {
553553
add_csr(CSR_MTOPI, std::make_shared<mtopi_csr_t>(proc, CSR_MTOPI));
554+
add_csr(CSR_MTOPEI, std::make_shared<topei_csr_t>(proc, CSR_MTOPEI, proc->imsic->m));
554555
if (xlen == 32) {
555556
add_supervisor_csr(CSR_MVIEN, std::make_shared<rv32_low_csr_t>(proc, CSR_MVIEN, mvien));
556557
add_supervisor_csr(CSR_MVIENH, std::make_shared<rv32_high_csr_t>(proc, CSR_MVIENH, mvien));
@@ -567,7 +568,9 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
567568
if (proc->extension_enabled_const(EXT_SSAIA)) { // Included by EXT_SMAIA
568569
csr_t_p nonvirtual_stopi = std::make_shared<nonvirtual_stopi_csr_t>(proc, CSR_STOPI);
569570
add_supervisor_csr(CSR_STOPI, std::make_shared<virtualized_with_special_permission_csr_t>(proc, nonvirtual_stopi, vstopi));
570-
add_supervisor_csr(CSR_STOPEI, std::make_shared<inaccessible_csr_t>(proc, CSR_STOPEI));
571+
auto vstopei = std::make_shared<vstopei_csr_t>(proc, CSR_VSTOPEI);
572+
auto nonvirtual_stopei = std::make_shared<nonvirtual_stopei_csr_t>(proc, CSR_STOPEI, proc->imsic->s);
573+
add_supervisor_csr(CSR_STOPEI, std::make_shared<virtualized_with_special_permission_csr_t>(proc, nonvirtual_stopei, vstopei));
571574
auto hvien = std::make_shared<aia_csr_t>(proc, CSR_HVIEN, 0, 0);
572575
auto hviprio1 = std::make_shared<aia_csr_t>(proc, CSR_HVIPRIO1, 0, 0);
573576
auto hviprio2 = std::make_shared<aia_csr_t>(proc, CSR_HVIPRIO2, 0, 0);
@@ -585,5 +588,6 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa)
585588
}
586589
add_hypervisor_csr(CSR_HVICTL, hvictl);
587590
add_hypervisor_csr(CSR_VSTOPI, vstopi);
591+
add_hypervisor_csr(CSR_VSTOPEI, vstopei);
588592
}
589593
}

riscv/csrs.cc

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

riscv/csrs.h

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

0 commit comments

Comments
 (0)