diff options
author | Korey Sewell <ksewell@umich.edu> | 2010-03-27 02:23:00 -0400 |
---|---|---|
committer | Korey Sewell <ksewell@umich.edu> | 2010-03-27 02:23:00 -0400 |
commit | 1c98bc5a567599f9fdc7d9940dbfe907091cb3b4 (patch) | |
tree | 9b9b7b9c049fdc4d34758cf1e62b9f3e33129586 /src/cpu | |
parent | 941399728fa387bd472041c01b6913e5b3e64909 (diff) | |
parent | 6b293c73fd19b73758547e1bfbe38a23d1800747 (diff) | |
download | gem5-1c98bc5a567599f9fdc7d9940dbfe907091cb3b4.tar.xz |
m5: merge inorder updates
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/inorder/resources/cache_unit.cc | 9 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 15 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 21 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 12 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 30 | ||||
-rw-r--r-- | src/cpu/translation.hh | 64 |
6 files changed, 105 insertions, 46 deletions
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 376ea8d26..d12f11a2c 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -443,6 +443,10 @@ CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) //The size of the data we're trying to read. int dataSize = sizeof(T); + if (inst->traceData) { + inst->traceData->setAddr(addr); + } + if (inst->split2ndAccess) { dataSize = inst->split2ndSize; cache_req->splitAccess = true; @@ -541,6 +545,11 @@ CacheUnit::write(DynInstPtr inst, T data, Addr addr, unsigned flags, //The size of the data we're trying to read. int dataSize = sizeof(T); + if (inst->traceData) { + inst->traceData->setAddr(addr); + inst->traceData->setData(data); + } + if (inst->split2ndAccess) { dataSize = inst->split2ndSize; cache_req->splitAccess = true; diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 05b4ca3e2..d96adffd5 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -351,10 +351,6 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) } } - // This will need a new way to tell if it has a dcache attached. - if (req->isUncacheable()) - recordEvent("Uncached Read"); - //If there's a fault, return it if (fault != NoFault) { if (req->isPrefetch()) { @@ -451,6 +447,7 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) if (traceData) { traceData->setAddr(addr); + traceData->setData(data); } //The block size of our peer. @@ -522,20 +519,10 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) } } - // This will need a new way to tell if it's hooked up to a cache or not. - if (req->isUncacheable()) - recordEvent("Uncached Write"); - //If there's a fault or we don't need to access a second cache line, //stop now. if (fault != NoFault || secondAddr <= addr) { - // If the write needs to have a fault on the access, consider - // calling changeStatus() and changing it to "bad addr write" - // or something. - if (traceData) { - traceData->setData(gtoh(data)); - } if (req->isLocked() && fault == NoFault) { assert(locked); locked = false; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 0104e1b1f..17ba6a10b 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -205,6 +205,27 @@ change_thread_state(ThreadID tid, int activate, int priority) { } +void +BaseSimpleCPU::prefetch(Addr addr, unsigned flags) +{ + if (traceData) { + traceData->setAddr(addr); + } + + // need to do this... +} + +void +BaseSimpleCPU::writeHint(Addr addr, int size, unsigned flags) +{ + if (traceData) { + traceData->setAddr(addr); + } + + // need to do this... +} + + Fault BaseSimpleCPU::copySrcTranslate(Addr src) { diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 39961fb88..87e211521 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -232,16 +232,8 @@ class BaseSimpleCPU : public BaseCPU Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); M5_DUMMY_RETURN} - void prefetch(Addr addr, unsigned flags) - { - // need to do this... - } - - void writeHint(Addr addr, int size, unsigned flags) - { - // need to do this... - } - + void prefetch(Addr addr, unsigned flags); + void writeHint(Addr addr, int size, unsigned flags); Fault copySrcTranslate(Addr src); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 221cb0d0d..b8fc5ab84 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -426,16 +426,16 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) int data_size = sizeof(T); BaseTLB::Mode mode = BaseTLB::Read; + if (traceData) { + traceData->setAddr(addr); + } + RequestPtr req = new Request(asid, addr, data_size, flags, pc, _cpuId, tid); Addr split_addr = roundDown(addr + data_size - 1, block_size); assert(split_addr <= addr || split_addr - addr < block_size); - // This will need a new way to tell if it's hooked up to a cache or not. - if (req->isUncacheable()) - recordEvent("Uncached Write"); - _status = DTBWaitResponse; if (split_addr > addr) { RequestPtr req1, req2; @@ -460,11 +460,6 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) thread->dtb->translateTiming(req, tc, translation, mode); } - if (traceData) { - traceData->setData(data); - traceData->setAddr(addr); - } - return NoFault; } @@ -548,16 +543,17 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) int data_size = sizeof(T); BaseTLB::Mode mode = BaseTLB::Write; + if (traceData) { + traceData->setAddr(addr); + traceData->setData(data); + } + RequestPtr req = new Request(asid, addr, data_size, flags, pc, _cpuId, tid); Addr split_addr = roundDown(addr + data_size - 1, block_size); assert(split_addr <= addr || split_addr - addr < block_size); - // This will need a new way to tell if it's hooked up to a cache or not. - if (req->isUncacheable()) - recordEvent("Uncached Write"); - T *dataP = new T; *dataP = TheISA::htog(data); _status = DTBWaitResponse; @@ -584,13 +580,7 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) thread->dtb->translateTiming(req, tc, translation, mode); } - if (traceData) { - traceData->setAddr(req->getVaddr()); - traceData->setData(data); - } - - // If the write needs to have a fault on the access, consider calling - // changeStatus() and changing it to "bad addr write" or something. + // Translation faults will be returned via finishTranslation() return NoFault; } diff --git a/src/cpu/translation.hh b/src/cpu/translation.hh index 33e810710..983a748cf 100644 --- a/src/cpu/translation.hh +++ b/src/cpu/translation.hh @@ -35,6 +35,16 @@ #include "sim/tlb.hh" +/** + * This class captures the state of an address translation. A translation + * can be split in two if the ISA supports it and the memory access crosses + * a page boundary. In this case, this class is shared by two data + * translations (below). Otherwise it is used by a single data translation + * class. When each part of the translation is finished, the finish + * function is called which will indicate whether the whole translation is + * completed or not. There are also functions for accessing parts of the + * translation state which deal with the possible split correctly. + */ class WholeTranslationState { protected: @@ -50,7 +60,10 @@ class WholeTranslationState uint64_t *res; BaseTLB::Mode mode; - /** Single translation state. */ + /** + * Single translation state. We set the number of outstanding + * translations to one and indicate that it is not split. + */ WholeTranslationState(RequestPtr _req, uint8_t *_data, uint64_t *_res, BaseTLB::Mode _mode) : outstanding(1), isSplit(false), mainReq(_req), sreqLow(NULL), @@ -60,7 +73,11 @@ class WholeTranslationState assert(mode == BaseTLB::Read || mode == BaseTLB::Write); } - /** Split translation state. */ + /** + * Split translation state. We copy all state into this class, set the + * number of outstanding translations to two and then mark this as a + * split translation. + */ WholeTranslationState(RequestPtr _req, RequestPtr _sreqLow, RequestPtr _sreqHigh, uint8_t *_data, uint64_t *_res, BaseTLB::Mode _mode) @@ -71,6 +88,13 @@ class WholeTranslationState assert(mode == BaseTLB::Read || mode == BaseTLB::Write); } + /** + * Finish part of a translation. If there is only one request then this + * translation is completed. If the request has been split in two then + * the outstanding count determines whether the translation is complete. + * In this case, flags from the split request are copied to the main + * request to make it easier to access them later on. + */ bool finish(Fault fault, int index) { @@ -89,6 +113,10 @@ class WholeTranslationState return outstanding == 0; } + /** + * Determine whether this translation produced a fault. Both parts of the + * translation must be checked if this is a split translation. + */ Fault getFault() const { @@ -102,36 +130,54 @@ class WholeTranslationState return NoFault; } + /** Remove all faults from the translation. */ void setNoFault() { faults[0] = faults[1] = NoFault; } + /** + * Check if this request is uncacheable. We only need to check the main + * request because the flags will have been copied here on a split + * translation. + */ bool isUncacheable() const { return mainReq->isUncacheable(); } + /** + * Check if this request is a prefetch. We only need to check the main + * request because the flags will have been copied here on a split + * translation. + */ bool isPrefetch() const { return mainReq->isPrefetch(); } + /** Get the physical address of this request. */ Addr getPaddr() const { return mainReq->getPaddr(); } + /** + * Get the flags associated with this request. We only need to access + * the main request because the flags will have been copied here on a + * split translation. + */ unsigned getFlags() { return mainReq->getFlags(); } + /** Delete all requests that make up this translation. */ void deleteReqs() { @@ -143,6 +189,16 @@ class WholeTranslationState } }; + +/** + * This class represents part of a data address translation. All state for + * the translation is held in WholeTranslationState (above). Therefore this + * class does not need to know whether the translation is split or not. The + * index variable determines this but is simply passed on to the state class. + * When this part of the translation is completed, finish is called. If the + * translation state class indicate that the whole translation is complete + * then the execution context is informed. + */ template <class ExecContext> class DataTranslation : public BaseTLB::Translation { @@ -163,6 +219,10 @@ class DataTranslation : public BaseTLB::Translation { } + /** + * Finish this part of the translation and indicate that the whole + * translation is complete if the state says so. + */ void finish(Fault fault, RequestPtr req, ThreadContext *tc, BaseTLB::Mode mode) |