Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various Fixes #25

Merged
merged 3 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions riscv/csrs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,14 @@ void mip_csr_t::backdoor_write_with_mask(const reg_t mask, const reg_t val) noex
this->val = (this->val & ~mask) | (val & mask);
}

reg_t mip_csr_t::read_pre_val() const noexcept {
return pre_val;
}

void mip_csr_t::write_pre_val(const reg_t val) noexcept {
pre_val = val;
}

reg_t mip_csr_t::write_mask() const noexcept {
const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0;
const reg_t vssip_int = proc->extension_enabled('H') ? MIP_VSSIP : 0;
Expand Down
11 changes: 11 additions & 0 deletions riscv/csrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,20 @@ class mip_or_mie_csr_t: public csr_t {
class mip_csr_t: public mip_or_mie_csr_t {
public:
mip_csr_t(processor_t* const proc, const reg_t addr);
virtual reg_t read_pre_val() const noexcept;
// The pre_val of MIP is used to determine if an interrupt will be taken at
// the beginning of an instruction step. Whilst the actual CSR value is the
// one accessed by any CSR instruction that may be executed.
//
// Nothing updates the value to become the pre_val. This is designed for use
// with co-simulation where the co-simulation environment is expected to do
// suitable value and pre_val updates before every step.
virtual void write_pre_val(const reg_t val) noexcept;

// Does not log. Used by external things (clint) that wiggle bits in mip.
void backdoor_write_with_mask(const reg_t mask, const reg_t val) noexcept;
protected:
reg_t pre_val;
private:
virtual reg_t write_mask() const noexcept override;
};
Expand Down
4 changes: 0 additions & 4 deletions riscv/mmu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,6 @@ reg_t reg_from_bytes(size_t len, const uint8_t* bytes)

bool mmu_t::mmio_ok(reg_t addr, access_type type)
{
// Disallow access to debug region when not in debug mode
if (addr >= DEBUG_START && addr <= DEBUG_END && proc && !proc->state.debug_mode)
return false;

return true;
}

Expand Down
4 changes: 2 additions & 2 deletions riscv/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "simif.h"
#include "processor.h"
#include "memtracer.h"
#include "byteorder.h"
#include "fesvr/byteorder.h"
#include "triggers.h"
#include <stdlib.h>
#include <vector>
Expand Down Expand Up @@ -418,6 +418,7 @@ class mmu_t
blocksz = size;
}

bool pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode);
private:
simif_t* sim;
processor_t* proc;
Expand Down Expand Up @@ -493,7 +494,6 @@ class mmu_t
}

reg_t pmp_homogeneous(reg_t addr, reg_t len);
bool pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode);

#ifdef RISCV_ENABLE_DUAL_ENDIAN
bool target_big_endian;
Expand Down
6 changes: 5 additions & 1 deletion riscv/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,11 @@ class processor_t : public abstract_device_t
throw trap_t(((reg_t)1 << get_isa().get_max_xlen()) - 1 - NMI_INTERRUPT_NUM);
}

take_interrupt(state.mip->read() & state.mie->read());
// Interrupt is based on the 'pre_val' of MIP which is set by the
// co-simulation environment. This can differ from the actual value which is
// what is observed by CSR instructions. This models the case where the MIP
// changes whilst an instruction is stalled in the ID/EX stage.
take_interrupt(state.mip->read_pre_val() & state.mie->read());
}
void take_interrupt(reg_t mask); // take first enabled interrupt in mask
void take_trap(trap_t& t, reg_t epc); // take an exception
Expand Down