diff options
Diffstat (limited to 'src/arch/riscv/tlb.cc')
-rw-r--r-- | src/arch/riscv/tlb.cc | 99 |
1 files changed, 70 insertions, 29 deletions
diff --git a/src/arch/riscv/tlb.cc b/src/arch/riscv/tlb.cc index ffb135c5a..494ec4c67 100644 --- a/src/arch/riscv/tlb.cc +++ b/src/arch/riscv/tlb.cc @@ -41,6 +41,7 @@ #include "arch/riscv/faults.hh" #include "arch/riscv/pagetable.hh" #include "arch/riscv/pra_constants.hh" +#include "arch/riscv/system.hh" #include "arch/riscv/utility.hh" #include "base/inifile.hh" #include "base/str.hh" @@ -285,42 +286,82 @@ TLB::regStats() Fault TLB::translateInst(const RequestPtr &req, ThreadContext *tc) { - if (FullSystem) - panic("translateInst not implemented in RISC-V.\n"); - - Process * p = tc->getProcessPtr(); + if (FullSystem) { + /** + * check if we simulate a bare metal system + * if so, we have no tlb, phys addr == virt addr + */ + if (static_cast<RiscvSystem *>(tc->getSystemPtr())->isBareMetal()) + req->setFlags(Request::PHYSICAL); + + if (req->getFlags() & Request::PHYSICAL) { + /** + * we simply set the virtual address to physical address + */ + req->setPaddr(req->getVaddr()); + return checkCacheability(req); + } else { + /** + * as we currently support bare metal only, we throw a panic, + * if it is not a bare metal system + */ + panic("translateInst not implemented in RISC-V.\n"); + } + } else { + Process * p = tc->getProcessPtr(); - Fault fault = p->pTable->translate(req); - if (fault != NoFault) - return fault; + Fault fault = p->pTable->translate(req); + if (fault != NoFault) + return fault; - return NoFault; + return NoFault; + } } Fault TLB::translateData(const RequestPtr &req, ThreadContext *tc, bool write) { - if (FullSystem) - panic("translateData not implemented in RISC-V.\n"); - - // In the O3 CPU model, sometimes a memory access will be speculatively - // executed along a branch that will end up not being taken where the - // address is invalid. In that case, return a fault rather than trying - // to translate it (which will cause a panic). Since RISC-V allows - // unaligned memory accesses, this should only happen if the request's - // length is long enough to wrap around from the end of the memory to the - // start. - assert(req->getSize() > 0); - if (req->getVaddr() + req->getSize() - 1 < req->getVaddr()) - return make_shared<GenericPageTableFault>(req->getVaddr()); - - Process * p = tc->getProcessPtr(); - - Fault fault = p->pTable->translate(req); - if (fault != NoFault) - return fault; - - return NoFault; + if (FullSystem) { + /** + * check if we simulate a bare metal system + * if so, we have no tlb, phys addr == virt addr + */ + if (static_cast<RiscvSystem *>(tc->getSystemPtr())->isBareMetal()) + req->setFlags(Request::PHYSICAL); + + if (req->getFlags() & Request::PHYSICAL) { + /** + * we simply set the virtual address to physical address + */ + req->setPaddr(req->getVaddr()); + return checkCacheability(req); + } else { + /** + * as we currently support bare metal only, we throw a panic, + * if it is not a bare metal system + */ + panic("translateData not implemented in RISC-V.\n"); + } + } else { + // In the O3 CPU model, sometimes a memory access will be speculatively + // executed along a branch that will end up not being taken where the + // address is invalid. In that case, return a fault rather than trying + // to translate it (which will cause a panic). Since RISC-V allows + // unaligned memory accesses, this should only happen if the request's + // length is long enough to wrap around from the end of the memory to + // the start. + assert(req->getSize() > 0); + if (req->getVaddr() + req->getSize() - 1 < req->getVaddr()) + return make_shared<GenericPageTableFault>(req->getVaddr()); + + Process * p = tc->getProcessPtr(); + + Fault fault = p->pTable->translate(req); + if (fault != NoFault) + return fault; + + return NoFault; + } } Fault |