diff --git a/src/arch/generic/mmu.hh b/src/arch/generic/mmu.hh index 976527397a..79e53dcf45 100644 --- a/src/arch/generic/mmu.hh +++ b/src/arch/generic/mmu.hh @@ -103,7 +103,7 @@ class BaseMMU : public SimObject return getTlb(mode)->finalizePhysical(req, tc, mode); } - void takeOverFrom(BaseMMU *old_mmu); + virtual void takeOverFrom(BaseMMU *old_mmu); public: BaseTLB* dtb; diff --git a/src/arch/riscv/RiscvMMU.py b/src/arch/riscv/RiscvMMU.py index 4ff477ec61..38f1da924a 100644 --- a/src/arch/riscv/RiscvMMU.py +++ b/src/arch/riscv/RiscvMMU.py @@ -35,6 +35,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from m5.params import * + from m5.objects.BaseMMU import BaseMMU from m5.objects.RiscvTLB import RiscvTLB from m5.objects.PMAChecker import PMAChecker @@ -45,7 +47,7 @@ class RiscvMMU(BaseMMU): cxx_header = 'arch/riscv/mmu.hh' itb = RiscvTLB() dtb = RiscvTLB() - pma_checker = PMAChecker() + pma_checker = Param.PMAChecker(PMAChecker(), "PMA Checker") @classmethod def walkerPorts(cls): diff --git a/src/arch/riscv/RiscvTLB.py b/src/arch/riscv/RiscvTLB.py index b419262390..05ff521dff 100644 --- a/src/arch/riscv/RiscvTLB.py +++ b/src/arch/riscv/RiscvTLB.py @@ -43,7 +43,7 @@ class RiscvPagetableWalker(ClockedObject): num_squash_per_cycle = Param.Unsigned(4, "Number of outstanding walks that can be squashed per cycle") # Grab the pma_checker from the MMU - pma_checker = Param.PMAChecker(Parent.any, "PMA Chekcer") + pma_checker = Param.PMAChecker(Parent.any, "PMA Checker") class RiscvTLB(BaseTLB): type = 'RiscvTLB' @@ -53,4 +53,4 @@ class RiscvTLB(BaseTLB): walker = Param.RiscvPagetableWalker(\ RiscvPagetableWalker(), "page table walker") # Grab the pma_checker from the MMU - pma_checker = Param.PMAChecker(Parent.any, "PMA Chekcer") + pma_checker = Param.PMAChecker(Parent.any, "PMA Checker") diff --git a/src/arch/riscv/mmu.hh b/src/arch/riscv/mmu.hh index 322f0afb87..ce3ce307ac 100644 --- a/src/arch/riscv/mmu.hh +++ b/src/arch/riscv/mmu.hh @@ -40,6 +40,7 @@ #include "arch/generic/mmu.hh" #include "arch/riscv/isa.hh" +#include "arch/riscv/pma_checker.hh" #include "arch/riscv/tlb.hh" #include "params/RiscvMMU.hh" @@ -49,8 +50,10 @@ namespace RiscvISA { class MMU : public BaseMMU { public: + PMAChecker *pma; + MMU(const RiscvMMUParams &p) - : BaseMMU(p) + : BaseMMU(p), pma(p.pma_checker) {} PrivilegeMode @@ -64,6 +67,14 @@ class MMU : public BaseMMU { return static_cast(dtb)->getWalker(); } + + void + takeOverFrom(BaseMMU *old_mmu) override + { + MMU *ommu = dynamic_cast(old_mmu); + BaseMMU::takeOverFrom(ommu); + pma->takeOverFrom(ommu->pma); + } }; } // namespace RiscvISA diff --git a/src/arch/riscv/pma_checker.cc b/src/arch/riscv/pma_checker.cc index 32cb66d70a..d36dc1dcb8 100644 --- a/src/arch/riscv/pma_checker.cc +++ b/src/arch/riscv/pma_checker.cc @@ -81,3 +81,9 @@ PMAChecker::isUncacheable(PacketPtr pkt) { return isUncacheable(pkt->getAddrRange()); } + +void +PMAChecker::takeOverFrom(PMAChecker *old) +{ + uncacheable = old->uncacheable; +} diff --git a/src/arch/riscv/pma_checker.hh b/src/arch/riscv/pma_checker.hh index 5833dbe610..298d4a0a72 100644 --- a/src/arch/riscv/pma_checker.hh +++ b/src/arch/riscv/pma_checker.hh @@ -74,6 +74,8 @@ class PMAChecker : public SimObject bool isUncacheable(const AddrRange &range); bool isUncacheable(const Addr &addr, const unsigned size); bool isUncacheable(PacketPtr pkt); + + void takeOverFrom(PMAChecker *old); }; #endif // __ARCH_RISCV_PMA_CHECKER_HH__ diff --git a/src/arch/riscv/tlb.cc b/src/arch/riscv/tlb.cc index 5109d2adfc..b7b09849dc 100644 --- a/src/arch/riscv/tlb.cc +++ b/src/arch/riscv/tlb.cc @@ -519,3 +519,9 @@ TLB::TlbStats::TlbStats(Stats::Group *parent) readAccesses + writeAccesses) { } + +Port * +TLB::getTableWalkerPort() +{ + return &walker->getPort("port"); +} \ No newline at end of file diff --git a/src/arch/riscv/tlb.hh b/src/arch/riscv/tlb.hh index 8dcf0fcf21..9c7172a26c 100644 --- a/src/arch/riscv/tlb.hh +++ b/src/arch/riscv/tlb.hh @@ -92,7 +92,7 @@ class TLB : public BaseTLB Walker *getWalker(); - void takeOverFrom(BaseTLB *otlb) override {} + void takeOverFrom(BaseTLB *old) override {} TlbEntry *insert(Addr vpn, const TlbEntry &entry); void flushAll() override; @@ -108,6 +108,18 @@ class TLB : public BaseTLB void serialize(CheckpointOut &cp) const override; void unserialize(CheckpointIn &cp) override; + /** + * Get the table walker port. This is used for + * migrating port connections during a CPU takeOverFrom() + * call. For architectures that do not have a table walker, + * NULL is returned, hence the use of a pointer rather than a + * reference. For RISC-V this method will always return a valid + * port pointer. + * + * @return A pointer to the walker port + */ + Port *getTableWalkerPort() override; + Addr translateWithTLB(Addr vaddr, uint16_t asid, Mode mode); Fault translateAtomic(const RequestPtr &req, diff --git a/src/dev/riscv/plic.cc b/src/dev/riscv/plic.cc index 60ac192201..2183183b87 100644 --- a/src/dev/riscv/plic.cc +++ b/src/dev/riscv/plic.cc @@ -354,17 +354,18 @@ Plic::readClaim(Register32& reg, const int context_id) context_id, max_int_id); clear(max_int_id); reg.update(max_int_id); + return reg.get(); } else { DPRINTF(Plic, "Claim already cleared - context: %d, interrupt ID: %d\n", context_id, max_int_id); - reg.update(0); + return 0; } } else { - warn("PLIC claim failed (not completed) - context: %d", context_id); - reg.update(0); + warn("PLIC claim repeated (not completed) - context: %d, last: %d", + context_id, lastID[context_id]); + return lastID[context_id]; } - return reg.get(); } void @@ -381,6 +382,7 @@ Plic::writeClaim(Register32& reg, const uint32_t& data, const int context_id) DPRINTF(Plic, "Complete - context: %d, interrupt ID: %d\n", context_id, reg.get()); + updateInt(); } void @@ -445,11 +447,11 @@ Plic::updateInt() uint32_t max_id = output.maxID[i]; uint32_t priority = output.maxPriority[i]; uint32_t threshold = registers.threshold[i].get(); - if (priority > threshold && max_id > 0) { + if (priority > threshold && max_id > 0 && lastID[i] == 0) { DPRINTF(Plic, "Int posted - thread: %d, int id: %d, ", thread_id, int_id); - DPRINTF(Plic, + DPRINTFR(Plic, "pri: %d, thres: %d\n", priority, threshold); intrctrl->post(thread_id, int_id, 0); } else { @@ -457,7 +459,7 @@ Plic::updateInt() DPRINTF(Plic, "Int filtered - thread: %d, int id: %d, ", thread_id, int_id); - DPRINTF(Plic, + DPRINTFR(Plic, "pri: %d, thres: %d\n", priority, threshold); } intrctrl->clear(thread_id, int_id, 0); @@ -499,6 +501,12 @@ Plic::serialize(CheckpointOut &cp) const SERIALIZE_SCALAR(n_outputs); SERIALIZE_CONTAINER(output.maxID); SERIALIZE_CONTAINER(output.maxPriority); + SERIALIZE_CONTAINER(pendingPriority); + for (int i=0; i < effPriority.size(); i++) { + arrayParamOut(cp, std::string("effPriority") + + std::to_string(i), effPriority[i]); + } + SERIALIZE_CONTAINER(lastID); } void @@ -541,4 +549,11 @@ Plic::unserialize(CheckpointIn &cp) } UNSERIALIZE_CONTAINER(output.maxID); UNSERIALIZE_CONTAINER(output.maxPriority); + UNSERIALIZE_CONTAINER(pendingPriority); + for (int i=0; i < effPriority.size(); i++) { + arrayParamIn(cp, std::string("effPriority") + + std::to_string(i), effPriority[i]); + } + UNSERIALIZE_CONTAINER(lastID); + updateInt(); }