class AlphaTLB(BaseTLB):
type = 'AlphaTLB'
cxx_class = 'AlphaISA::TLB'
- size = Param.Int(64, "TLB size")
+ size = Param.Int("TLB size")
+
+class AlphaDTB(AlphaTLB):
+ size = 64
+
+class AlphaITB(AlphaTLB):
+ size = 48
}
Fault
-TLB::translateAtomic(RequestPtr req, ThreadContext *tc,
- bool write, bool execute)
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
{
- if (execute)
+ if (mode == Execute)
return translateInst(req, tc);
else
- return translateData(req, tc, write);
+ return translateData(req, tc, mode == Write);
}
void
TLB::translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation,
- bool write, bool execute)
+ Translation *translation, Mode mode)
{
assert(translation);
- translation->finish(translateAtomic(req, tc, write, execute),
- req, tc, write, execute);
+ translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
}
/* end namespace AlphaISA */ }
Fault translateInst(RequestPtr req, ThreadContext *tc);
public:
- Fault translateAtomic(RequestPtr req, ThreadContext *tc,
- bool write = false, bool execute = false);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
void translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation,
- bool write = false, bool execute = false);
+ Translation *translation, Mode mode);
};
} // namespace AlphaISA
}
Fault
-TLB::translateAtomic(RequestPtr req, ThreadContext *tc,
- bool write, bool execute)
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
{
- if (execute)
+ if (mode == Execute)
return translateInst(req, tc);
else
- return translateData(req, tc, write);
+ return translateData(req, tc, mode == Write);
}
void
TLB::translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write, bool execute)
+ Translation *translation, Mode mode)
{
assert(translation);
- translation->finish(translateAtomic(req, tc, write, execute),
- req, tc, write, execute);
+ translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
}
void regStats();
- Fault translateAtomic(RequestPtr req, ThreadContext *tc,
- bool write=false, bool execute=false);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
void translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write=false, bool execute=false);
+ Translation *translation, Mode mode);
private:
Fault translateInst(RequestPtr req, ThreadContext *tc);
};
Fault
-TLB::translateAtomic(RequestPtr req, ThreadContext *tc,
- bool write, bool execute)
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
{
- if (execute)
+ if (mode == Execute)
return translateInst(req, tc);
else
- return translateData(req, tc, write);
+ return translateData(req, tc, mode == Write);
}
void
TLB::translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write, bool execute)
+ Translation *translation, Mode mode)
{
assert(translation);
- translation->finish(translateAtomic(req, tc, write, execute),
- req, tc, write, execute);
+ translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
}
#if FULL_SYSTEM
void dumpAll();
- Fault translateAtomic(RequestPtr req,
- ThreadContext *tc, bool write=false, bool execute=false);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
void translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write=false, bool execute=false);
+ Translation *translation, Mode mode);
#if FULL_SYSTEM
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
#include "base/bitunion.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
+#include "sim/tlb.hh"
#include <string>
X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
{}
- PageFault(Addr _addr, bool present, bool write,
- bool user, bool reserved, bool fetch) :
+ PageFault(Addr _addr, bool present, BaseTLB::Mode mode,
+ bool user, bool reserved) :
X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
{
PageFaultErrorCode code = 0;
code.present = present;
- code.write = write;
+ code.write = (mode == BaseTLB::Write);
code.user = user;
code.reserved = reserved;
- code.fetch = fetch;
+ code.fetch = (mode == BaseTLB::Execute);
errorCode = code;
}
bool uncacheable = pte.pcd;
Addr nextRead = 0;
bool doWrite = false;
- bool badNX = pte.nx && execute && enableNX;
+ bool badNX = pte.nx && mode == BaseTLB::Write && enableNX;
switch(state) {
case LongPML4:
DPRINTF(PageTableWalker,
Fault
Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
- RequestPtr _req, bool _write, bool _execute)
+ RequestPtr _req, BaseTLB::Mode _mode)
{
assert(state == Ready);
tc = _tc;
req = _req;
Addr vaddr = req->getVaddr();
- execute = _execute;
- write = _write;
+ mode = _mode;
translation = _translation;
VAddr addr = vaddr;
* well.
*/
bool delayedResponse;
- Fault fault = tlb->translate(req, tc, NULL, write, execute,
+ Fault fault = tlb->translate(req, tc, NULL, mode,
delayedResponse, true);
assert(!delayedResponse);
// Let the CPU continue.
- translation->finish(fault, req, tc, write);
+ translation->finish(fault, req, tc, mode);
} else {
// There was a fault during the walk. Let the CPU know.
- translation->finish(timingFault, req, tc, write);
+ translation->finish(timingFault, req, tc, mode);
}
}
} else if (pkt->wasNacked()) {
{
DPRINTF(PageTableWalker, "Raising page fault.\n");
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
- return new PageFault(entry.vaddr, present, write,
- m5reg.cpl == 3, false, execute && enableNX);
+ if (mode == BaseTLB::Execute && !enableNX)
+ mode = BaseTLB::Read;
+ return new PageFault(entry.vaddr, present, mode, m5reg.cpl == 3, false);
}
}
// Kick off the state machine.
Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
- RequestPtr req, bool write, bool execute);
+ RequestPtr req, BaseTLB::Mode mode);
// Clean up after the state machine.
void
stop()
State nextState;
int size;
bool enableNX;
- bool write, execute, user;
+ BaseTLB::Mode mode;
+ bool user;
TlbEntry entry;
Fault pageFault(bool present);
}
Fault
-TLB::translate(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write, bool execute,
- bool &delayedResponse, bool timing)
+TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
+ Mode mode, bool &delayedResponse, bool timing)
{
delayedResponse = false;
Addr vaddr = req->getVaddr();
bool expandDown = false;
SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) {
- if (!attr.writable && write)
+ if (!attr.writable && mode == Write)
return new GeneralProtection(0);
- if (!attr.readable && !write && !execute)
+ if (!attr.readable && mode == Read)
return new GeneralProtection(0);
expandDown = attr.expandDown;
TlbEntry *entry = lookup(vaddr);
if (!entry) {
#if FULL_SYSTEM
- Fault fault = walker->start(tc, translation, req,
- write, execute);
+ Fault fault = walker->start(tc, translation, req, mode);
if (timing || fault != NoFault) {
// This gets ignored in atomic mode.
delayedResponse = true;
Process *p = tc->getProcessPtr();
TlbEntry newEntry;
bool success = p->pTable->lookup(vaddr, newEntry);
- if(!success && !execute) {
+ if(!success && mode != Execute) {
p->checkAndAllocNextPage(vaddr);
success = p->pTable->lookup(vaddr, newEntry);
}
bool inUser = (csAttr.dpl == 3 &&
!(flags & (CPL0FlagBit << FlagShift)));
if ((inUser && !entry->user) ||
- (write && !entry->writable)) {
+ (mode == Write && !entry->writable)) {
// The page must have been present to get into the TLB in
// the first place. We'll assume the reserved bits are
// fine even though we're not checking them.
- return new PageFault(vaddr, true, write,
- inUser, false, execute);
+ return new PageFault(vaddr, true, mode, inUser, false);
}
};
Fault
-TLB::translateAtomic(RequestPtr req, ThreadContext *tc,
- bool write, bool execute)
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
{
bool delayedResponse;
- return TLB::translate(req, tc, NULL, write,
- execute, delayedResponse, false);
+ return TLB::translate(req, tc, NULL, mode, delayedResponse, false);
}
void
TLB::translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write, bool execute)
+ Translation *translation, Mode mode)
{
bool delayedResponse;
assert(translation);
- Fault fault = TLB::translate(req, tc, translation,
- write, execute, delayedResponse, true);
+ Fault fault =
+ TLB::translate(req, tc, translation, mode, delayedResponse, true);
if (!delayedResponse)
- translation->finish(fault, req, tc, write, execute);
+ translation->finish(fault, req, tc, mode);
}
#if FULL_SYSTEM
EntryList entryList;
Fault translate(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write, bool execute,
+ Translation *translation, Mode mode,
bool &delayedResponse, bool timing);
public:
- Fault translateAtomic(RequestPtr req, ThreadContext *tc,
- bool write = false, bool execute = false);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
void translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation,
- bool write = false, bool execute = false);
+ Translation *translation, Mode mode);
#if FULL_SYSTEM
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
default_tracer = ExeTracer()
if build_env['TARGET_ISA'] == 'alpha':
- from AlphaTLB import AlphaTLB
+ from AlphaTLB import AlphaDTB, AlphaITB
if build_env['FULL_SYSTEM']:
from AlphaInterrupts import AlphaInterrupts
elif build_env['TARGET_ISA'] == 'sparc':
if build_env['FULL_SYSTEM']:
from MipsInterrupts import MipsInterrupts
elif build_env['TARGET_ISA'] == 'arm':
- from ArmTLB import ArmTLB, ArmDTB, ArmITB, ArmUTB
+ from ArmTLB import ArmDTB
if build_env['FULL_SYSTEM']:
from ArmInterrupts import ArmInterrupts
interrupts = Param.SparcInterrupts(
SparcInterrupts(), "Interrupt Controller")
elif build_env['TARGET_ISA'] == 'alpha':
- dtb = Param.AlphaTLB(AlphaTLB(size=64), "Data TLB")
- itb = Param.AlphaTLB(AlphaTLB(size=48), "Instruction TLB")
+ dtb = Param.AlphaTLB(AlphaDTB(), "Data TLB")
+ itb = Param.AlphaTLB(AlphaITB(), "Instruction TLB")
if build_env['FULL_SYSTEM']:
interrupts = Param.AlphaInterrupts(
AlphaInterrupts(), "Interrupt Controller")
MipsInterrupts(), "Interrupt Controller")
elif build_env['TARGET_ISA'] == 'arm':
UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
- dtb = Param.ArmDTB(ArmDTB(), "Data TLB")
- itb = Param.ArmITB(ArmITB(), "Instruction TLB")
- tlb = Param.ArmUTB(ArmUTB(), "Unified TLB")
+ dtb = Param.ArmTLB(ArmDTB(), "Data TLB")
+ itb = Param.ArmTLB(ArmITB(), "Instruction TLB")
if build_env['FULL_SYSTEM']:
interrupts = Param.ArmInterrupts(
ArmInterrupts(), "Interrupt Controller")
#include "cpu/static_inst.hh"
#include "mem/packet.hh"
#include "sim/system.hh"
+#include "sim/tlb.hh"
/**
* @file
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->contextId(), threadNumber);
- fault = cpu->dtb->translateAtomic(req, thread->getTC(), false);
+ fault = cpu->dtb->translateAtomic(req, thread->getTC(), BaseTLB::Read);
if (req->isUncacheable())
isUncacheable = true;
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->contextId(), threadNumber);
- fault = cpu->dtb->translateAtomic(req, thread->getTC(), true);
+ fault = cpu->dtb->translateAtomic(req, thread->getTC(), BaseTLB::Write);
if (req->isUncacheable())
isUncacheable = true;
// Translate the instruction request.
fault = cpu->itb->translateAtomic(mem_req, cpu->thread[tid]->getTC(),
- false, true);
+ BaseTLB::Execute);
// In the case of faults, the fetch stage may need to stall and wait
// for the ITB miss to be handled.
req->setVirt(0, addr, dataSize, flags, thread->readPC());
// translate to physical address
- Fault fault = thread->dtb->translateAtomic(req, tc, false);
+ Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Read);
// Now do the access.
if (fault == NoFault) {
req->setVirt(0, addr, dataSize, flags, thread->readPC());
// translate to physical address
- Fault fault = thread->dtb->translateAtomic(req, tc, true);
+ Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Write);
// Now do the access.
if (fault == NoFault) {
bool fromRom = isRomMicroPC(thread->readMicroPC());
if (!fromRom && !curMacroStaticInst) {
setupFetchRequest(&ifetch_req);
- fault = thread->itb->translateAtomic(&ifetch_req, tc, false, true);
+ fault = thread->itb->translateAtomic(&ifetch_req, tc,
+ BaseTLB::Execute);
}
if (fault == NoFault) {
typedef SplitDataTranslation::WholeTranslationState WholeState;
WholeState *state = new WholeState(req1, req2, req,
- (uint8_t *)(new T), true);
+ (uint8_t *)(new T), BaseTLB::Read);
thread->dtb->translateTiming(req1, tc,
- new SplitDataTranslation(this, 0, state), false);
+ new SplitDataTranslation(this, 0, state), BaseTLB::Read);
thread->dtb->translateTiming(req2, tc,
- new SplitDataTranslation(this, 1, state), false);
+ new SplitDataTranslation(this, 1, state), BaseTLB::Read);
} else {
- thread->dtb->translateTiming(req, tc,
- new DataTranslation(this, (uint8_t *)(new T), NULL, true),
- false);
+ DataTranslation *translation =
+ new DataTranslation(this, (uint8_t *)(new T), NULL, BaseTLB::Read);
+ thread->dtb->translateTiming(req, tc, translation, BaseTLB::Read);
}
if (traceData) {
typedef SplitDataTranslation::WholeTranslationState WholeState;
WholeState *state = new WholeState(req1, req2, req,
- (uint8_t *)dataP, false);
+ (uint8_t *)dataP, BaseTLB::Write);
thread->dtb->translateTiming(req1, tc,
- new SplitDataTranslation(this, 0, state), true);
+ new SplitDataTranslation(this, 0, state), BaseTLB::Write);
thread->dtb->translateTiming(req2, tc,
- new SplitDataTranslation(this, 1, state), true);
+ new SplitDataTranslation(this, 1, state), BaseTLB::Write);
} else {
- thread->dtb->translateTiming(req, tc,
- new DataTranslation(this, (uint8_t *)dataP, res, false),
- true);
+ DataTranslation *translation =
+ new DataTranslation(this, (uint8_t *)dataP, res, BaseTLB::Write);
+ thread->dtb->translateTiming(req, tc, translation, BaseTLB::Write);
}
if (traceData) {
Request *ifetch_req = new Request();
ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0);
setupFetchRequest(ifetch_req);
- thread->itb->translateTiming(ifetch_req, tc,
- &fetchTranslation, false, true);
+ thread->itb->translateTiming(ifetch_req, tc, &fetchTranslation,
+ BaseTLB::Execute);
} else {
_status = IcacheWaitResponse;
completeIfetch(NULL);
TimingSimpleCPU *cpu;
public:
- FetchTranslation(TimingSimpleCPU *_cpu) : cpu(_cpu)
+ FetchTranslation(TimingSimpleCPU *_cpu)
+ : cpu(_cpu)
{}
- void finish(Fault fault, RequestPtr req,
- ThreadContext *tc, bool write, bool execute)
+ void
+ finish(Fault fault, RequestPtr req, ThreadContext *tc,
+ BaseTLB::Mode mode)
{
cpu->sendFetch(fault, req, tc);
}
TimingSimpleCPU *cpu;
uint8_t *data;
uint64_t *res;
- bool read;
+ BaseTLB::Mode mode;
public:
DataTranslation(TimingSimpleCPU *_cpu,
- uint8_t *_data, uint64_t *_res, bool _read) :
- cpu(_cpu), data(_data), res(_res), read(_read)
- {}
+ uint8_t *_data, uint64_t *_res, BaseTLB::Mode _mode)
+ : cpu(_cpu), data(_data), res(_res), mode(_mode)
+ {
+ assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
+ }
void
- finish(Fault fault, RequestPtr req,
- ThreadContext *tc, bool write, bool execute)
+ finish(Fault fault, RequestPtr req, ThreadContext *tc,
+ BaseTLB::Mode mode)
{
- cpu->sendData(fault, req, data, res, read);
+ assert(mode == this->mode);
+ cpu->sendData(fault, req, data, res, mode == BaseTLB::Read);
delete this;
}
};
RequestPtr mainReq;
Fault faults[2];
uint8_t *data;
- bool read;
+ BaseTLB::Mode mode;
WholeTranslationState(RequestPtr req1, RequestPtr req2,
- RequestPtr main, uint8_t *_data, bool _read)
+ RequestPtr main, uint8_t *data, BaseTLB::Mode mode)
{
+ assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
+
outstanding = 2;
requests[0] = req1;
requests[1] = req2;
mainReq = main;
faults[0] = faults[1] = NoFault;
- data = _data;
- read = _read;
+ this->data = data;
+ this->mode = mode;
}
};
WholeTranslationState *state;
SplitDataTranslation(TimingSimpleCPU *_cpu, int _index,
- WholeTranslationState *_state) :
- cpu(_cpu), index(_index), state(_state)
+ WholeTranslationState *_state)
+ : cpu(_cpu), index(_index), state(_state)
{}
void
- finish(Fault fault, RequestPtr req,
- ThreadContext *tc, bool write, bool execute)
+ finish(Fault fault, RequestPtr req, ThreadContext *tc,
+ BaseTLB::Mode mode)
{
assert(state);
assert(state->outstanding);
state->requests[1],
state->mainReq,
state->data,
- state->read);
+ state->mode == BaseTLB::Read);
delete state;
}
delete this;
#include "sim/tlb.hh"
Fault
-GenericTLB::translateAtomic(RequestPtr req, ThreadContext * tc, bool, bool)
+GenericTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode)
{
#if FULL_SYSTEM
panic("Generic translation shouldn't be used in full system mode.\n");
void
GenericTLB::translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool write, bool execute)
+ Translation *translation, Mode mode)
{
assert(translation);
- translation->finish(translateAtomic(req, tc, write, execute),
- req, tc, write, execute);
+ translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
}
void
class BaseTLB : public SimObject
{
protected:
- BaseTLB(const Params *p) : SimObject(p)
+ BaseTLB(const Params *p)
+ : SimObject(p)
{}
+ public:
+ enum Mode { Read, Write, Execute };
+
public:
virtual void demapPage(Addr vaddr, uint64_t asn) = 0;
* be responsible for cleaning itself up which will happen in this
* function. Once it's called, the object is no longer valid.
*/
- virtual void finish(Fault fault, RequestPtr req,
- ThreadContext *tc, bool write=false, bool execute=false) = 0;
+ virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
+ Mode mode) = 0;
};
};
class GenericTLB : public BaseTLB
{
protected:
- GenericTLB(const Params *p) : BaseTLB(p)
+ GenericTLB(const Params *p)
+ : BaseTLB(p)
{}
public:
void demapPage(Addr vaddr, uint64_t asn);
- Fault translateAtomic(RequestPtr req, ThreadContext *tc,
- bool=false, bool=false);
+ Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
void translateTiming(RequestPtr req, ThreadContext *tc,
- Translation *translation, bool=false, bool=false);
+ Translation *translation, Mode mode);
};
#endif // __ARCH_SPARC_TLB_HH__