tlb: More fixing of unified TLB

This commit is contained in:
Nathan Binkert 2009-04-08 22:21:27 -07:00
parent 7b5a96f06b
commit e0de2c3443
20 changed files with 130 additions and 129 deletions

View file

@ -34,4 +34,10 @@ from BaseTLB import BaseTLB
class AlphaTLB(BaseTLB): class AlphaTLB(BaseTLB):
type = 'AlphaTLB' type = 'AlphaTLB'
cxx_class = 'AlphaISA::TLB' 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

View file

@ -607,23 +607,20 @@ TLB::index(bool advance)
} }
Fault Fault
TLB::translateAtomic(RequestPtr req, ThreadContext *tc, TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
bool write, bool execute)
{ {
if (execute) if (mode == Execute)
return translateInst(req, tc); return translateInst(req, tc);
else else
return translateData(req, tc, write); return translateData(req, tc, mode == Write);
} }
void void
TLB::translateTiming(RequestPtr req, ThreadContext *tc, TLB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, Translation *translation, Mode mode)
bool write, bool execute)
{ {
assert(translation); assert(translation);
translation->finish(translateAtomic(req, tc, write, execute), translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
req, tc, write, execute);
} }
/* end namespace AlphaISA */ } /* end namespace AlphaISA */ }

View file

@ -141,11 +141,9 @@ class TLB : public BaseTLB
Fault translateInst(RequestPtr req, ThreadContext *tc); Fault translateInst(RequestPtr req, ThreadContext *tc);
public: public:
Fault translateAtomic(RequestPtr req, ThreadContext *tc, Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
bool write = false, bool execute = false);
void translateTiming(RequestPtr req, ThreadContext *tc, void translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, Translation *translation, Mode mode);
bool write = false, bool execute = false);
}; };
} // namespace AlphaISA } // namespace AlphaISA

View file

@ -562,22 +562,20 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
} }
Fault Fault
TLB::translateAtomic(RequestPtr req, ThreadContext *tc, TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
bool write, bool execute)
{ {
if (execute) if (mode == Execute)
return translateInst(req, tc); return translateInst(req, tc);
else else
return translateData(req, tc, write); return translateData(req, tc, mode == Write);
} }
void void
TLB::translateTiming(RequestPtr req, ThreadContext *tc, TLB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write, bool execute) Translation *translation, Mode mode)
{ {
assert(translation); assert(translation);
translation->finish(translateAtomic(req, tc, write, execute), translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
req, tc, write, execute);
} }

View file

@ -138,10 +138,9 @@ class TLB : public BaseTLB
void regStats(); void regStats();
Fault translateAtomic(RequestPtr req, ThreadContext *tc, Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
bool write=false, bool execute=false);
void translateTiming(RequestPtr req, ThreadContext *tc, void translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write=false, bool execute=false); Translation *translation, Mode mode);
private: private:
Fault translateInst(RequestPtr req, ThreadContext *tc); Fault translateInst(RequestPtr req, ThreadContext *tc);

View file

@ -843,22 +843,20 @@ handleMmuRegAccess:
}; };
Fault Fault
TLB::translateAtomic(RequestPtr req, ThreadContext *tc, TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
bool write, bool execute)
{ {
if (execute) if (mode == Execute)
return translateInst(req, tc); return translateInst(req, tc);
else else
return translateData(req, tc, write); return translateData(req, tc, mode == Write);
} }
void void
TLB::translateTiming(RequestPtr req, ThreadContext *tc, TLB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write, bool execute) Translation *translation, Mode mode)
{ {
assert(translation); assert(translation);
translation->finish(translateAtomic(req, tc, write, execute), translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
req, tc, write, execute);
} }
#if FULL_SYSTEM #if FULL_SYSTEM

View file

@ -163,10 +163,9 @@ class TLB : public BaseTLB
void dumpAll(); void dumpAll();
Fault translateAtomic(RequestPtr req, Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
ThreadContext *tc, bool write=false, bool execute=false);
void translateTiming(RequestPtr req, ThreadContext *tc, void translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write=false, bool execute=false); Translation *translation, Mode mode);
#if FULL_SYSTEM #if FULL_SYSTEM
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);

View file

@ -61,6 +61,7 @@
#include "base/bitunion.hh" #include "base/bitunion.hh"
#include "base/misc.hh" #include "base/misc.hh"
#include "sim/faults.hh" #include "sim/faults.hh"
#include "sim/tlb.hh"
#include <string> #include <string>
@ -331,16 +332,16 @@ namespace X86ISA
X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr) X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
{} {}
PageFault(Addr _addr, bool present, bool write, PageFault(Addr _addr, bool present, BaseTLB::Mode mode,
bool user, bool reserved, bool fetch) : bool user, bool reserved) :
X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr) X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
{ {
PageFaultErrorCode code = 0; PageFaultErrorCode code = 0;
code.present = present; code.present = present;
code.write = write; code.write = (mode == BaseTLB::Write);
code.user = user; code.user = user;
code.reserved = reserved; code.reserved = reserved;
code.fetch = fetch; code.fetch = (mode == BaseTLB::Execute);
errorCode = code; errorCode = code;
} }

View file

@ -98,7 +98,7 @@ Walker::doNext(PacketPtr &write)
bool uncacheable = pte.pcd; bool uncacheable = pte.pcd;
Addr nextRead = 0; Addr nextRead = 0;
bool doWrite = false; bool doWrite = false;
bool badNX = pte.nx && execute && enableNX; bool badNX = pte.nx && mode == BaseTLB::Write && enableNX;
switch(state) { switch(state) {
case LongPML4: case LongPML4:
DPRINTF(PageTableWalker, DPRINTF(PageTableWalker,
@ -329,14 +329,13 @@ Walker::doNext(PacketPtr &write)
Fault Fault
Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
RequestPtr _req, bool _write, bool _execute) RequestPtr _req, BaseTLB::Mode _mode)
{ {
assert(state == Ready); assert(state == Ready);
tc = _tc; tc = _tc;
req = _req; req = _req;
Addr vaddr = req->getVaddr(); Addr vaddr = req->getVaddr();
execute = _execute; mode = _mode;
write = _write;
translation = _translation; translation = _translation;
VAddr addr = vaddr; VAddr addr = vaddr;
@ -451,14 +450,14 @@ Walker::recvTiming(PacketPtr pkt)
* well. * well.
*/ */
bool delayedResponse; bool delayedResponse;
Fault fault = tlb->translate(req, tc, NULL, write, execute, Fault fault = tlb->translate(req, tc, NULL, mode,
delayedResponse, true); delayedResponse, true);
assert(!delayedResponse); assert(!delayedResponse);
// Let the CPU continue. // Let the CPU continue.
translation->finish(fault, req, tc, write); translation->finish(fault, req, tc, mode);
} else { } else {
// There was a fault during the walk. Let the CPU know. // 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()) { } else if (pkt->wasNacked()) {
@ -563,8 +562,9 @@ Walker::pageFault(bool present)
{ {
DPRINTF(PageTableWalker, "Raising page fault.\n"); DPRINTF(PageTableWalker, "Raising page fault.\n");
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
return new PageFault(entry.vaddr, present, write, if (mode == BaseTLB::Execute && !enableNX)
m5reg.cpl == 3, false, execute && enableNX); mode = BaseTLB::Read;
return new PageFault(entry.vaddr, present, mode, m5reg.cpl == 3, false);
} }
} }

View file

@ -97,7 +97,7 @@ namespace X86ISA
// Kick off the state machine. // Kick off the state machine.
Fault start(ThreadContext * _tc, BaseTLB::Translation *translation, Fault start(ThreadContext * _tc, BaseTLB::Translation *translation,
RequestPtr req, bool write, bool execute); RequestPtr req, BaseTLB::Mode mode);
// Clean up after the state machine. // Clean up after the state machine.
void void
stop() stop()
@ -183,7 +183,8 @@ namespace X86ISA
State nextState; State nextState;
int size; int size;
bool enableNX; bool enableNX;
bool write, execute, user; BaseTLB::Mode mode;
bool user;
TlbEntry entry; TlbEntry entry;
Fault pageFault(bool present); Fault pageFault(bool present);

View file

@ -186,9 +186,8 @@ TLB::demapPage(Addr va, uint64_t asn)
} }
Fault Fault
TLB::translate(RequestPtr req, ThreadContext *tc, TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
Translation *translation, bool write, bool execute, Mode mode, bool &delayedResponse, bool timing)
bool &delayedResponse, bool timing)
{ {
delayedResponse = false; delayedResponse = false;
Addr vaddr = req->getVaddr(); Addr vaddr = req->getVaddr();
@ -577,9 +576,9 @@ TLB::translate(RequestPtr req, ThreadContext *tc,
bool expandDown = false; bool expandDown = false;
SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) { if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) {
if (!attr.writable && write) if (!attr.writable && mode == Write)
return new GeneralProtection(0); return new GeneralProtection(0);
if (!attr.readable && !write && !execute) if (!attr.readable && mode == Read)
return new GeneralProtection(0); return new GeneralProtection(0);
expandDown = attr.expandDown; expandDown = attr.expandDown;
@ -612,8 +611,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc,
TlbEntry *entry = lookup(vaddr); TlbEntry *entry = lookup(vaddr);
if (!entry) { if (!entry) {
#if FULL_SYSTEM #if FULL_SYSTEM
Fault fault = walker->start(tc, translation, req, Fault fault = walker->start(tc, translation, req, mode);
write, execute);
if (timing || fault != NoFault) { if (timing || fault != NoFault) {
// This gets ignored in atomic mode. // This gets ignored in atomic mode.
delayedResponse = true; delayedResponse = true;
@ -629,7 +627,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc,
Process *p = tc->getProcessPtr(); Process *p = tc->getProcessPtr();
TlbEntry newEntry; TlbEntry newEntry;
bool success = p->pTable->lookup(vaddr, newEntry); bool success = p->pTable->lookup(vaddr, newEntry);
if(!success && !execute) { if(!success && mode != Execute) {
p->checkAndAllocNextPage(vaddr); p->checkAndAllocNextPage(vaddr);
success = p->pTable->lookup(vaddr, newEntry); success = p->pTable->lookup(vaddr, newEntry);
} }
@ -648,12 +646,11 @@ TLB::translate(RequestPtr req, ThreadContext *tc,
bool inUser = (csAttr.dpl == 3 && bool inUser = (csAttr.dpl == 3 &&
!(flags & (CPL0FlagBit << FlagShift))); !(flags & (CPL0FlagBit << FlagShift)));
if ((inUser && !entry->user) || if ((inUser && !entry->user) ||
(write && !entry->writable)) { (mode == Write && !entry->writable)) {
// The page must have been present to get into the TLB in // The page must have been present to get into the TLB in
// the first place. We'll assume the reserved bits are // the first place. We'll assume the reserved bits are
// fine even though we're not checking them. // fine even though we're not checking them.
return new PageFault(vaddr, true, write, return new PageFault(vaddr, true, mode, inUser, false);
inUser, false, execute);
} }
@ -700,24 +697,22 @@ TLB::translate(RequestPtr req, ThreadContext *tc,
}; };
Fault Fault
TLB::translateAtomic(RequestPtr req, ThreadContext *tc, TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
bool write, bool execute)
{ {
bool delayedResponse; bool delayedResponse;
return TLB::translate(req, tc, NULL, write, return TLB::translate(req, tc, NULL, mode, delayedResponse, false);
execute, delayedResponse, false);
} }
void void
TLB::translateTiming(RequestPtr req, ThreadContext *tc, TLB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write, bool execute) Translation *translation, Mode mode)
{ {
bool delayedResponse; bool delayedResponse;
assert(translation); assert(translation);
Fault fault = TLB::translate(req, tc, translation, Fault fault =
write, execute, delayedResponse, true); TLB::translate(req, tc, translation, mode, delayedResponse, true);
if (!delayedResponse) if (!delayedResponse)
translation->finish(fault, req, tc, write, execute); translation->finish(fault, req, tc, mode);
} }
#if FULL_SYSTEM #if FULL_SYSTEM

View file

@ -127,16 +127,14 @@ namespace X86ISA
EntryList entryList; EntryList entryList;
Fault translate(RequestPtr req, ThreadContext *tc, Fault translate(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write, bool execute, Translation *translation, Mode mode,
bool &delayedResponse, bool timing); bool &delayedResponse, bool timing);
public: public:
Fault translateAtomic(RequestPtr req, ThreadContext *tc, Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
bool write = false, bool execute = false);
void translateTiming(RequestPtr req, ThreadContext *tc, void translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, Translation *translation, Mode mode);
bool write = false, bool execute = false);
#if FULL_SYSTEM #if FULL_SYSTEM
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);

View file

@ -38,7 +38,7 @@ import sys
default_tracer = ExeTracer() default_tracer = ExeTracer()
if build_env['TARGET_ISA'] == 'alpha': if build_env['TARGET_ISA'] == 'alpha':
from AlphaTLB import AlphaTLB from AlphaTLB import AlphaDTB, AlphaITB
if build_env['FULL_SYSTEM']: if build_env['FULL_SYSTEM']:
from AlphaInterrupts import AlphaInterrupts from AlphaInterrupts import AlphaInterrupts
elif build_env['TARGET_ISA'] == 'sparc': elif build_env['TARGET_ISA'] == 'sparc':
@ -54,7 +54,7 @@ elif build_env['TARGET_ISA'] == 'mips':
if build_env['FULL_SYSTEM']: if build_env['FULL_SYSTEM']:
from MipsInterrupts import MipsInterrupts from MipsInterrupts import MipsInterrupts
elif build_env['TARGET_ISA'] == 'arm': elif build_env['TARGET_ISA'] == 'arm':
from ArmTLB import ArmTLB, ArmDTB, ArmITB, ArmUTB from ArmTLB import ArmDTB
if build_env['FULL_SYSTEM']: if build_env['FULL_SYSTEM']:
from ArmInterrupts import ArmInterrupts from ArmInterrupts import ArmInterrupts
@ -89,8 +89,8 @@ class BaseCPU(MemObject):
interrupts = Param.SparcInterrupts( interrupts = Param.SparcInterrupts(
SparcInterrupts(), "Interrupt Controller") SparcInterrupts(), "Interrupt Controller")
elif build_env['TARGET_ISA'] == 'alpha': elif build_env['TARGET_ISA'] == 'alpha':
dtb = Param.AlphaTLB(AlphaTLB(size=64), "Data TLB") dtb = Param.AlphaTLB(AlphaDTB(), "Data TLB")
itb = Param.AlphaTLB(AlphaTLB(size=48), "Instruction TLB") itb = Param.AlphaTLB(AlphaITB(), "Instruction TLB")
if build_env['FULL_SYSTEM']: if build_env['FULL_SYSTEM']:
interrupts = Param.AlphaInterrupts( interrupts = Param.AlphaInterrupts(
AlphaInterrupts(), "Interrupt Controller") AlphaInterrupts(), "Interrupt Controller")
@ -109,9 +109,8 @@ class BaseCPU(MemObject):
MipsInterrupts(), "Interrupt Controller") MipsInterrupts(), "Interrupt Controller")
elif build_env['TARGET_ISA'] == 'arm': elif build_env['TARGET_ISA'] == 'arm':
UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?") UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
dtb = Param.ArmDTB(ArmDTB(), "Data TLB") dtb = Param.ArmTLB(ArmDTB(), "Data TLB")
itb = Param.ArmITB(ArmITB(), "Instruction TLB") itb = Param.ArmTLB(ArmITB(), "Instruction TLB")
tlb = Param.ArmUTB(ArmUTB(), "Unified TLB")
if build_env['FULL_SYSTEM']: if build_env['FULL_SYSTEM']:
interrupts = Param.ArmInterrupts( interrupts = Param.ArmInterrupts(
ArmInterrupts(), "Interrupt Controller") ArmInterrupts(), "Interrupt Controller")

View file

@ -46,6 +46,7 @@
#include "cpu/static_inst.hh" #include "cpu/static_inst.hh"
#include "mem/packet.hh" #include "mem/packet.hh"
#include "sim/system.hh" #include "sim/system.hh"
#include "sim/tlb.hh"
/** /**
* @file * @file
@ -860,7 +861,7 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
req->setVirt(asid, addr, sizeof(T), flags, this->PC); req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->contextId(), threadNumber); 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()) if (req->isUncacheable())
isUncacheable = true; isUncacheable = true;
@ -916,7 +917,7 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
req->setVirt(asid, addr, sizeof(T), flags, this->PC); req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->contextId(), threadNumber); 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()) if (req->isUncacheable())
isUncacheable = true; isUncacheable = true;

View file

@ -602,7 +602,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
// Translate the instruction request. // Translate the instruction request.
fault = cpu->itb->translateAtomic(mem_req, cpu->thread[tid]->getTC(), 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 // In the case of faults, the fetch stage may need to stall and wait
// for the ITB miss to be handled. // for the ITB miss to be handled.

View file

@ -314,7 +314,7 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
req->setVirt(0, addr, dataSize, flags, thread->readPC()); req->setVirt(0, addr, dataSize, flags, thread->readPC());
// translate to physical address // 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. // Now do the access.
if (fault == NoFault) { if (fault == NoFault) {
@ -452,7 +452,7 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
req->setVirt(0, addr, dataSize, flags, thread->readPC()); req->setVirt(0, addr, dataSize, flags, thread->readPC());
// translate to physical address // 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. // Now do the access.
if (fault == NoFault) { if (fault == NoFault) {
@ -609,7 +609,8 @@ AtomicSimpleCPU::tick()
bool fromRom = isRomMicroPC(thread->readMicroPC()); bool fromRom = isRomMicroPC(thread->readMicroPC());
if (!fromRom && !curMacroStaticInst) { if (!fromRom && !curMacroStaticInst) {
setupFetchRequest(&ifetch_req); setupFetchRequest(&ifetch_req);
fault = thread->itb->translateAtomic(&ifetch_req, tc, false, true); fault = thread->itb->translateAtomic(&ifetch_req, tc,
BaseTLB::Execute);
} }
if (fault == NoFault) { if (fault == NoFault) {

View file

@ -454,15 +454,15 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
typedef SplitDataTranslation::WholeTranslationState WholeState; typedef SplitDataTranslation::WholeTranslationState WholeState;
WholeState *state = new WholeState(req1, req2, req, WholeState *state = new WholeState(req1, req2, req,
(uint8_t *)(new T), true); (uint8_t *)(new T), BaseTLB::Read);
thread->dtb->translateTiming(req1, tc, thread->dtb->translateTiming(req1, tc,
new SplitDataTranslation(this, 0, state), false); new SplitDataTranslation(this, 0, state), BaseTLB::Read);
thread->dtb->translateTiming(req2, tc, thread->dtb->translateTiming(req2, tc,
new SplitDataTranslation(this, 1, state), false); new SplitDataTranslation(this, 1, state), BaseTLB::Read);
} else { } else {
thread->dtb->translateTiming(req, tc, DataTranslation *translation =
new DataTranslation(this, (uint8_t *)(new T), NULL, true), new DataTranslation(this, (uint8_t *)(new T), NULL, BaseTLB::Read);
false); thread->dtb->translateTiming(req, tc, translation, BaseTLB::Read);
} }
if (traceData) { if (traceData) {
@ -573,15 +573,15 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
typedef SplitDataTranslation::WholeTranslationState WholeState; typedef SplitDataTranslation::WholeTranslationState WholeState;
WholeState *state = new WholeState(req1, req2, req, WholeState *state = new WholeState(req1, req2, req,
(uint8_t *)dataP, false); (uint8_t *)dataP, BaseTLB::Write);
thread->dtb->translateTiming(req1, tc, thread->dtb->translateTiming(req1, tc,
new SplitDataTranslation(this, 0, state), true); new SplitDataTranslation(this, 0, state), BaseTLB::Write);
thread->dtb->translateTiming(req2, tc, thread->dtb->translateTiming(req2, tc,
new SplitDataTranslation(this, 1, state), true); new SplitDataTranslation(this, 1, state), BaseTLB::Write);
} else { } else {
thread->dtb->translateTiming(req, tc, DataTranslation *translation =
new DataTranslation(this, (uint8_t *)dataP, res, false), new DataTranslation(this, (uint8_t *)dataP, res, BaseTLB::Write);
true); thread->dtb->translateTiming(req, tc, translation, BaseTLB::Write);
} }
if (traceData) { if (traceData) {
@ -671,8 +671,8 @@ TimingSimpleCPU::fetch()
Request *ifetch_req = new Request(); Request *ifetch_req = new Request();
ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0); ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0);
setupFetchRequest(ifetch_req); setupFetchRequest(ifetch_req);
thread->itb->translateTiming(ifetch_req, tc, thread->itb->translateTiming(ifetch_req, tc, &fetchTranslation,
&fetchTranslation, false, true); BaseTLB::Execute);
} else { } else {
_status = IcacheWaitResponse; _status = IcacheWaitResponse;
completeIfetch(NULL); completeIfetch(NULL);

View file

@ -102,11 +102,13 @@ class TimingSimpleCPU : public BaseSimpleCPU
TimingSimpleCPU *cpu; TimingSimpleCPU *cpu;
public: public:
FetchTranslation(TimingSimpleCPU *_cpu) : cpu(_cpu) FetchTranslation(TimingSimpleCPU *_cpu)
: cpu(_cpu)
{} {}
void finish(Fault fault, RequestPtr req, void
ThreadContext *tc, bool write, bool execute) finish(Fault fault, RequestPtr req, ThreadContext *tc,
BaseTLB::Mode mode)
{ {
cpu->sendFetch(fault, req, tc); cpu->sendFetch(fault, req, tc);
} }
@ -119,19 +121,22 @@ class TimingSimpleCPU : public BaseSimpleCPU
TimingSimpleCPU *cpu; TimingSimpleCPU *cpu;
uint8_t *data; uint8_t *data;
uint64_t *res; uint64_t *res;
bool read; BaseTLB::Mode mode;
public: public:
DataTranslation(TimingSimpleCPU *_cpu, DataTranslation(TimingSimpleCPU *_cpu,
uint8_t *_data, uint64_t *_res, bool _read) : uint8_t *_data, uint64_t *_res, BaseTLB::Mode _mode)
cpu(_cpu), data(_data), res(_res), read(_read) : cpu(_cpu), data(_data), res(_res), mode(_mode)
{} {
assert(mode == BaseTLB::Read || mode == BaseTLB::Write);
}
void void
finish(Fault fault, RequestPtr req, finish(Fault fault, RequestPtr req, ThreadContext *tc,
ThreadContext *tc, bool write, bool execute) 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; delete this;
} }
}; };
@ -147,18 +152,20 @@ class TimingSimpleCPU : public BaseSimpleCPU
RequestPtr mainReq; RequestPtr mainReq;
Fault faults[2]; Fault faults[2];
uint8_t *data; uint8_t *data;
bool read; BaseTLB::Mode mode;
WholeTranslationState(RequestPtr req1, RequestPtr req2, 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; outstanding = 2;
requests[0] = req1; requests[0] = req1;
requests[1] = req2; requests[1] = req2;
mainReq = main; mainReq = main;
faults[0] = faults[1] = NoFault; faults[0] = faults[1] = NoFault;
data = _data; this->data = data;
read = _read; this->mode = mode;
} }
}; };
@ -167,13 +174,13 @@ class TimingSimpleCPU : public BaseSimpleCPU
WholeTranslationState *state; WholeTranslationState *state;
SplitDataTranslation(TimingSimpleCPU *_cpu, int _index, SplitDataTranslation(TimingSimpleCPU *_cpu, int _index,
WholeTranslationState *_state) : WholeTranslationState *_state)
cpu(_cpu), index(_index), state(_state) : cpu(_cpu), index(_index), state(_state)
{} {}
void void
finish(Fault fault, RequestPtr req, finish(Fault fault, RequestPtr req, ThreadContext *tc,
ThreadContext *tc, bool write, bool execute) BaseTLB::Mode mode)
{ {
assert(state); assert(state);
assert(state->outstanding); assert(state->outstanding);
@ -185,7 +192,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
state->requests[1], state->requests[1],
state->mainReq, state->mainReq,
state->data, state->data,
state->read); state->mode == BaseTLB::Read);
delete state; delete state;
} }
delete this; delete this;

View file

@ -34,7 +34,7 @@
#include "sim/tlb.hh" #include "sim/tlb.hh"
Fault Fault
GenericTLB::translateAtomic(RequestPtr req, ThreadContext * tc, bool, bool) GenericTLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode)
{ {
#if FULL_SYSTEM #if FULL_SYSTEM
panic("Generic translation shouldn't be used in full system mode.\n"); panic("Generic translation shouldn't be used in full system mode.\n");
@ -51,11 +51,10 @@ GenericTLB::translateAtomic(RequestPtr req, ThreadContext * tc, bool, bool)
void void
GenericTLB::translateTiming(RequestPtr req, ThreadContext *tc, GenericTLB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool write, bool execute) Translation *translation, Mode mode)
{ {
assert(translation); assert(translation);
translation->finish(translateAtomic(req, tc, write, execute), translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
req, tc, write, execute);
} }
void void

View file

@ -42,9 +42,13 @@ class Packet;
class BaseTLB : public SimObject class BaseTLB : public SimObject
{ {
protected: protected:
BaseTLB(const Params *p) : SimObject(p) BaseTLB(const Params *p)
: SimObject(p)
{} {}
public:
enum Mode { Read, Write, Execute };
public: public:
virtual void demapPage(Addr vaddr, uint64_t asn) = 0; virtual void demapPage(Addr vaddr, uint64_t asn) = 0;
@ -59,24 +63,24 @@ class BaseTLB : public SimObject
* be responsible for cleaning itself up which will happen in this * be responsible for cleaning itself up which will happen in this
* function. Once it's called, the object is no longer valid. * function. Once it's called, the object is no longer valid.
*/ */
virtual void finish(Fault fault, RequestPtr req, virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
ThreadContext *tc, bool write=false, bool execute=false) = 0; Mode mode) = 0;
}; };
}; };
class GenericTLB : public BaseTLB class GenericTLB : public BaseTLB
{ {
protected: protected:
GenericTLB(const Params *p) : BaseTLB(p) GenericTLB(const Params *p)
: BaseTLB(p)
{} {}
public: public:
void demapPage(Addr vaddr, uint64_t asn); void demapPage(Addr vaddr, uint64_t asn);
Fault translateAtomic(RequestPtr req, ThreadContext *tc, Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
bool=false, bool=false);
void translateTiming(RequestPtr req, ThreadContext *tc, void translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, bool=false, bool=false); Translation *translation, Mode mode);
}; };
#endif // __ARCH_SPARC_TLB_HH__ #endif // __ARCH_SPARC_TLB_HH__