Skip to content

Commit 20a7354

Browse files
committed
Fix hvip.VSEIP and hvip.VSTIP, so they don't observe platform-specific interrupts or CSR hgeip bits
The H extension defines that bits VSEIP, VSTIP, and VSSIP of hvip are writable. (The other bits of hvip are read-only 0.) Only hip.VSSIP (mip.VSSIP) is an alias of hvip.VSSIP. The hip.VSEIP is the logical-OR of hvip.VSEIP, selected bit of hgeip by hstatus.VGEIN, and platform-specific external interrupt signals to VS-level, e.g., from AIA. The hip.VSTIP is the logical-OR of hvip.VSTIP and platform-specific timer interrupt signals to VS-level, e.g., from Sstc. Thus, the read values of hvip.VSEIP and hvip.VSTIP differ from the ones of hip.VSEIP and hip.VSTIP (mip.VSEIP and mip.VSTIP). In other words, the hvip isn't an alias (proxy) of mip. The current aliasing (proxy) implementation does not provide the desired behavior for hvip.VSEIP and hvip.VSTIP. An ISA-level behavior difference is that any platform-specific external and timer interrupt signals directed to VS-level should not be observable through the hvip. For instance, the hvip should not observe the virtual timer interrupt signal from the vstimecmp CSR (Sstc extension), which isn't true in the current implementation. Additionally, the hvip should not observe the virtual external interrupt signal from the IMSIC device (AIA extension). Another ISA-level behavior difference is that the hgeip and hstatus.VGEIN also should not affect hvip.VSEIP, which isn't true in the current implementation. This commit fixes the issue by giving the hvip a specialized class, hvip_csr_t. The hvip_csr_t aliases the hvip.VSSIP to the mip.VSSIP but decouples the hvip.VSEIP and hvip.VSTIP from mip.VSEIP and mip.VSTIP. Additionally, the commit updates the read value of mip to be the logical-OR of hvip.VSEIP, hvip.VSTIP, and other sources.
1 parent 7c89063 commit 20a7354

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

riscv/csrs.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,10 @@ mip_csr_t::mip_csr_t(processor_t* const proc, const reg_t addr):
728728
mip_or_mie_csr_t(proc, addr) {
729729
}
730730

731+
reg_t mip_csr_t::read() const noexcept {
732+
return val | state->hvip->basic_csr_t::read();
733+
}
734+
731735
void mip_csr_t::backdoor_write_with_mask(const reg_t mask, const reg_t val) noexcept {
732736
this->val = (this->val & ~mask) | (val & mask);
733737
}
@@ -1717,3 +1721,16 @@ void srmcfg_csr_t::verify_permissions(insn_t insn, bool write) const {
17171721
if (state->v)
17181722
throw trap_virtual_instruction(insn.bits());
17191723
}
1724+
1725+
hvip_csr_t::hvip_csr_t(processor_t* const proc, const reg_t addr, const reg_t init):
1726+
basic_csr_t(proc, addr, init) {
1727+
}
1728+
1729+
reg_t hvip_csr_t::read() const noexcept {
1730+
return basic_csr_t::read() | (state->mip->read() & MIP_VSSIP); // hvip.VSSIP is an alias of mip.VSSIP
1731+
}
1732+
1733+
bool hvip_csr_t::unlogged_write(const reg_t val) noexcept {
1734+
state->mip->write_with_mask(MIP_VSSIP, val); // hvip.VSSIP is an alias of mip.VSSIP
1735+
return basic_csr_t::unlogged_write(val & (MIP_VSEIP | MIP_VSTIP));
1736+
}

riscv/csrs.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ typedef std::shared_ptr<misa_csr_t> misa_csr_t_p;
349349
class mip_or_mie_csr_t: public csr_t {
350350
public:
351351
mip_or_mie_csr_t(processor_t* const proc, const reg_t addr);
352-
virtual reg_t read() const noexcept override final;
352+
virtual reg_t read() const noexcept override;
353353

354354
void write_with_mask(const reg_t mask, const reg_t val) noexcept;
355355

@@ -364,6 +364,7 @@ class mip_or_mie_csr_t: public csr_t {
364364
class mip_csr_t: public mip_or_mie_csr_t {
365365
public:
366366
mip_csr_t(processor_t* const proc, const reg_t addr);
367+
virtual reg_t read() const noexcept override final;
367368

368369
// Does not log. Used by external things (clint) that wiggle bits in mip.
369370
void backdoor_write_with_mask(const reg_t mask, const reg_t val) noexcept;
@@ -850,4 +851,14 @@ class srmcfg_csr_t: public masked_csr_t {
850851
srmcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init);
851852
virtual void verify_permissions(insn_t insn, bool write) const override;
852853
};
854+
855+
class hvip_csr_t : public basic_csr_t {
856+
public:
857+
hvip_csr_t(processor_t* const proc, const reg_t addr, const reg_t init);
858+
reg_t read() const noexcept override;
859+
protected:
860+
virtual bool unlogged_write(const reg_t val) noexcept override;
861+
};
862+
863+
typedef std::shared_ptr<hvip_csr_t> hvip_csr_t_p;
853864
#endif

riscv/processor.cc

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -304,15 +304,6 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
304304
0 // shiftamt
305305
);
306306

307-
auto hvip_accr = std::make_shared<generic_int_accessor_t>(
308-
this,
309-
MIP_VS_MASK, // read_mask
310-
MIP_VS_MASK, // ip_write_mask
311-
MIP_VS_MASK, // ie_write_mask
312-
generic_int_accessor_t::mask_mode_t::NONE,
313-
0 // shiftamt
314-
);
315-
316307
auto vsip_vsie_accr = std::make_shared<generic_int_accessor_t>(
317308
this,
318309
MIP_VS_MASK, // read_mask
@@ -327,7 +318,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
327318
csrmap[CSR_VSIP] = vsip;
328319
csrmap[CSR_SIP] = std::make_shared<virtualized_csr_t>(proc, nonvirtual_sip, vsip);
329320
csrmap[CSR_HIP] = std::make_shared<mip_proxy_csr_t>(proc, CSR_HIP, hip_hie_accr);
330-
csrmap[CSR_HVIP] = std::make_shared<mip_proxy_csr_t>(proc, CSR_HVIP, hvip_accr);
321+
csrmap[CSR_HVIP] = hvip = std::make_shared<hvip_csr_t>(proc, CSR_HVIP, 0);
331322

332323
auto nonvirtual_sie = std::make_shared<mie_proxy_csr_t>(proc, CSR_SIE, sip_sie_accr);
333324
auto vsie = std::make_shared<mie_proxy_csr_t>(proc, CSR_VSIE, vsip_vsie_accr);

riscv/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct state_t
128128
csr_t_p htval;
129129
csr_t_p htinst;
130130
csr_t_p hgatp;
131+
hvip_csr_t_p hvip;
131132
sstatus_csr_t_p sstatus;
132133
vsstatus_csr_t_p vsstatus;
133134
csr_t_p vstvec;

0 commit comments

Comments
 (0)