arch: Add a MMUTranslationGen class to the BaseMMU.

This translation generator is returned by the new version of the
TranslateFunctional method which translates a region rather than a
single address. That method is currently virtual with a default
implementation which is not overloaded, but the plan is for the other
MMUs to override that method and inject their own page size minimally.
In the future, the MMUTranslationGen class and the implementations in
the MMUs may be updated so that they can, for instance, handle varying
page sizes across a single translation.

Change-Id: I39479f0f0e8150fc6e3e1a7097a0c8bd8d22d4e0
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50759
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-09-20 21:37:24 -07:00
parent 3b48aa4d4c
commit 1f9fc43e72
3 changed files with 65 additions and 1 deletions

View File

@@ -166,6 +166,8 @@ class MMU : public BaseMMU
void init() override;
using BaseMMU::translateFunctional;
/**
* Do a functional lookup on the TLB (for debugging)
* and don't modify any internal state

View File

@@ -43,6 +43,8 @@
#include "arch/generic/mmu.hh"
#include "arch/generic/tlb.hh"
#include "cpu/thread_context.hh"
#include "sim/system.hh"
namespace gem5
{
@@ -126,6 +128,40 @@ BaseMMU::finalizePhysical(const RequestPtr &req, ThreadContext *tc,
return getTlb(mode)->finalizePhysical(req, tc, mode);
}
BaseMMU::MMUTranslationGen::MMUTranslationGen(Addr page_bytes,
Addr new_start, Addr new_size, ThreadContext *new_tc,
BaseMMU *new_mmu, BaseMMU::Mode new_mode, Request::Flags new_flags) :
TranslationGen(new_start, new_size), tc(new_tc), cid(tc->contextId()),
mmu(new_mmu), mode(new_mode), flags(new_flags),
pageBytes(page_bytes)
{}
void
BaseMMU::MMUTranslationGen::translate(Range &range) const
{
Addr next = roundUp(range.vaddr, pageBytes);
if (next == range.vaddr)
next += pageBytes;
range.size = std::min(range.size, next - range.vaddr);
auto req = std::make_shared<Request>(
range.vaddr, range.size, flags, Request::funcRequestorId, 0, cid);
range.fault = mmu->translateFunctional(req, tc, mode);
if (range.fault == NoFault)
range.paddr = req->getPaddr();
}
TranslationGenPtr
BaseMMU::translateFunctional(Addr start, Addr size, ThreadContext *tc,
BaseMMU::Mode mode, Request::Flags flags)
{
return TranslationGenPtr(new MMUTranslationGen(
tc->getSystemPtr()->getPageBytes(), start, size, tc, this,
mode, flags));
}
void
BaseMMU::takeOverFrom(BaseMMU *old_mmu)
{

View File

@@ -40,8 +40,9 @@
#include <set>
#include "params/BaseMMU.hh"
#include "mem/request.hh"
#include "mem/translation_gen.hh"
#include "params/BaseMMU.hh"
#include "sim/sim_object.hh"
namespace gem5
@@ -122,6 +123,31 @@ class BaseMMU : public SimObject
translateFunctional(const RequestPtr &req, ThreadContext *tc,
Mode mode);
class MMUTranslationGen : public TranslationGen
{
private:
ThreadContext *tc;
ContextID cid;
BaseMMU *mmu;
BaseMMU::Mode mode;
Request::Flags flags;
const Addr pageBytes;
void translate(Range &range) const override;
public:
MMUTranslationGen(Addr page_bytes, Addr new_start, Addr new_size,
ThreadContext *new_tc, BaseMMU *new_mmu,
BaseMMU::Mode new_mode, Request::Flags new_flags);
};
/**
* Returns a translation generator for a region of virtual addresses,
* instead of directly translating a specific address.
*/
virtual TranslationGenPtr translateFunctional(Addr start, Addr size,
ThreadContext *tc, BaseMMU::Mode mode, Request::Flags flags);
virtual Fault
finalizePhysical(const RequestPtr &req, ThreadContext *tc,
Mode mode) const;