diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2010-08-13 06:16:02 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2010-08-13 06:16:02 -0700 |
commit | aa8c6e9c959eab4d516bc07593bea20ade9ad80c (patch) | |
tree | 3e0112e567da5dc1aa019f85458fbd9e37ad0cf2 /src/cpu/inorder | |
parent | 65dbcc6ea170e05ca2370a9a265a61668250fa98 (diff) | |
download | gem5-aa8c6e9c959eab4d516bc07593bea20ade9ad80c.tar.xz |
CPU: Add readBytes and writeBytes functions to the exec contexts.
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r-- | src/cpu/inorder/cpu.cc | 122 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.hh | 9 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.cc | 35 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.hh | 7 | ||||
-rw-r--r-- | src/cpu/inorder/resources/cache_unit.cc | 170 | ||||
-rw-r--r-- | src/cpu/inorder/resources/cache_unit.hh | 9 |
6 files changed, 76 insertions, 276 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 75873d97d..059996b07 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -1518,135 +1518,25 @@ InOrderCPU::getDTBPtr() return dtb_res->tlb(); } -template <class T> Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) +InOrderCPU::read(DynInstPtr inst, Addr addr, + uint8_t *data, unsigned size, unsigned flags) { //@TODO: Generalize name "CacheUnit" to "MemUnit" just in case // you want to run w/out caches? CacheUnit *cache_res = dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx)); - return cache_res->read(inst, addr, data, flags); + return cache_res->read(inst, addr, data, size, flags); } -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, Twin32_t &data, unsigned flags); - -template -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, Twin64_t &data, unsigned flags); - -template -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, uint64_t &data, unsigned flags); - -template -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, uint32_t &data, unsigned flags); - -template -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, uint16_t &data, unsigned flags); - -template -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, uint8_t &data, unsigned flags); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, double &data, unsigned flags) -{ - return read(inst, addr, *(uint64_t*)&data, flags); -} - -template<> -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, float &data, unsigned flags) -{ - return read(inst, addr, *(uint32_t*)&data, flags); -} - - -template<> -Fault -InOrderCPU::read(DynInstPtr inst, Addr addr, int32_t &data, unsigned flags) -{ - return read(inst, addr, (uint32_t&)data, flags); -} - -template <class T> Fault -InOrderCPU::write(DynInstPtr inst, T data, Addr addr, unsigned flags, - uint64_t *write_res) +InOrderCPU::write(DynInstPtr inst, uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *write_res) { //@TODO: Generalize name "CacheUnit" to "MemUnit" just in case // you want to run w/out caches? CacheUnit *cache_res = dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx)); - return cache_res->write(inst, data, addr, flags, write_res); -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template -Fault -InOrderCPU::write(DynInstPtr inst, Twin32_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderCPU::write(DynInstPtr inst, Twin64_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderCPU::write(DynInstPtr inst, uint64_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderCPU::write(DynInstPtr inst, uint32_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderCPU::write(DynInstPtr inst, uint16_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -InOrderCPU::write(DynInstPtr inst, uint8_t data, Addr addr, - unsigned flags, uint64_t *res); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -InOrderCPU::write(DynInstPtr inst, double data, Addr addr, unsigned flags, - uint64_t *res) -{ - return write(inst, *(uint64_t*)&data, addr, flags, res); -} - -template<> -Fault -InOrderCPU::write(DynInstPtr inst, float data, Addr addr, unsigned flags, - uint64_t *res) -{ - return write(inst, *(uint32_t*)&data, addr, flags, res); -} - - -template<> -Fault -InOrderCPU::write(DynInstPtr inst, int32_t data, Addr addr, unsigned flags, - uint64_t *res) -{ - return write(inst, (uint32_t)data, addr, flags, res); + return cache_res->write(inst, data, size, addr, flags, write_res); } diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 6676d78cf..450829e64 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -523,15 +523,14 @@ class InOrderCPU : public BaseCPU /** Forwards an instruction read to the appropriate data * resource (indexes into Resource Pool thru "dataPortIdx") */ - template <class T> - Fault read(DynInstPtr inst, Addr addr, T &data, unsigned flags); + Fault read(DynInstPtr inst, Addr addr, + uint8_t *data, unsigned size, unsigned flags); /** Forwards an instruction write. to the appropriate data * resource (indexes into Resource Pool thru "dataPortIdx") */ - template <class T> - Fault write(DynInstPtr inst, T data, Addr addr, unsigned flags, - uint64_t *write_res = NULL); + Fault write(DynInstPtr inst, uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *write_res = NULL); /** Forwards an instruction prefetch to the appropriate data * resource (indexes into Resource Pool thru "dataPortIdx") diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index 13ec7a3ff..5486dedee 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -610,6 +610,13 @@ InOrderDynInst::deallocateContext(int thread_num) this->cpu->deallocateContext(thread_num); } +Fault +InOrderDynInst::readBytes(Addr addr, uint8_t *data, + unsigned size, unsigned flags) +{ + return cpu->read(this, addr, data, size, flags); +} + template<class T> inline Fault InOrderDynInst::read(Addr addr, T &data, unsigned flags) @@ -618,8 +625,11 @@ InOrderDynInst::read(Addr addr, T &data, unsigned flags) traceData->setAddr(addr); traceData->setData(data); } - - return cpu->read(this, addr, data, flags); + Fault fault = readBytes(addr, (uint8_t *)&data, sizeof(T), flags); + data = TheISA::gtoh(data); + if (traceData) + traceData->setData(data); + return fault; } #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -663,20 +673,29 @@ InOrderDynInst::read(Addr addr, int32_t &data, unsigned flags) return read(addr, (uint32_t&)data, flags); } +Fault +InOrderDynInst::writeBytes(uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *res) +{ + assert(sizeof(storeData) >= size); + memcpy(&storeData, data, size); + return cpu->write(this, (uint8_t *)&storeData, size, addr, flags, res); +} + template<class T> inline Fault InOrderDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res) { - if (traceData) { - traceData->setAddr(addr); - traceData->setData(data); - } - storeData = data; DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n", threadNumber, seqNum, storeData); - return cpu->write(this, data, addr, flags, res); + if (traceData) { + traceData->setAddr(addr); + traceData->setData(data); + } + storeData = TheISA::htog(data); + return writeBytes((uint8_t*)&data, sizeof(T), addr, flags, res); } #ifndef DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index ffb795e1e..0d42f4696 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -334,7 +334,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted PacketDataPtr splitMemData; RequestPtr splitMemReq; - int splitTotalSize; + int totalSize; int split2ndSize; Addr split2ndAddr; bool split2ndAccess; @@ -637,6 +637,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted template <class T> Fault read(Addr addr, T &data, unsigned flags); + Fault readBytes(Addr addr, uint8_t *data, unsigned size, unsigned flags); + /** * Does a write to a given address. * @param data The data to be written. @@ -649,6 +651,9 @@ class InOrderDynInst : public FastAlloc, public RefCounted Fault write(T data, Addr addr, unsigned flags, uint64_t *res); + Fault writeBytes(uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *res); + /** Initiates a memory access - Calculate Eff. Addr & Initiate Memory * Access Only valid for memory operations. */ diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 2ab9e889e..4d21f527e 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -443,9 +443,9 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size, return cache_req->fault; } -template <class T> Fault -CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) +CacheUnit::read(DynInstPtr inst, Addr addr, + uint8_t *data, unsigned size, unsigned flags) { CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(findRequest(inst)); assert(cache_req && "Can't Find Instruction for Read!"); @@ -454,14 +454,15 @@ CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) unsigned blockSize = this->cachePort->peerBlockSize(); //The size of the data we're trying to read. - int dataSize = sizeof(T); + int fullSize = size; + inst->totalSize = size; if (inst->traceData) { inst->traceData->setAddr(addr); } if (inst->split2ndAccess) { - dataSize = inst->split2ndSize; + size = inst->split2ndSize; cache_req->splitAccess = true; cache_req->split2ndAccess = true; @@ -473,7 +474,7 @@ CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) //The address of the second part of this access if it needs to be split //across a cache line boundary. - Addr secondAddr = roundDown(addr + dataSize - 1, blockSize); + Addr secondAddr = roundDown(addr + size - 1, blockSize); if (secondAddr > addr && !inst->split2ndAccess) { @@ -483,8 +484,7 @@ CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) // Save All "Total" Split Information // ============================== inst->splitInst = true; - inst->splitMemData = new uint8_t[dataSize]; - inst->splitTotalSize = dataSize; + inst->splitMemData = new uint8_t[size]; if (!inst->splitInstSked) { // Schedule Split Read/Complete for Instruction @@ -517,22 +517,22 @@ CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) // Split Information for First Access // ============================== - dataSize = secondAddr - addr; + size = secondAddr - addr; cache_req->splitAccess = true; // Split Information for Second Access // ============================== - inst->split2ndSize = addr + sizeof(T) - secondAddr; + inst->split2ndSize = addr + fullSize - secondAddr; inst->split2ndAddr = secondAddr; - inst->split2ndDataPtr = inst->splitMemData + dataSize; + inst->split2ndDataPtr = inst->splitMemData + size; inst->split2ndFlags = flags; } - doTLBAccess(inst, cache_req, dataSize, flags, TheISA::TLB::Read); + doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Read); if (cache_req->fault == NoFault) { if (!cache_req->splitAccess) { - cache_req->reqData = new uint8_t[dataSize]; + cache_req->reqData = new uint8_t[size]; doCacheAccess(inst, NULL); } else { if (!inst->split2ndAccess) { @@ -548,10 +548,9 @@ CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags) return cache_req->fault; } -template <class T> Fault -CacheUnit::write(DynInstPtr inst, T data, Addr addr, unsigned flags, - uint64_t *write_res) +CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *write_res) { CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(findRequest(inst)); assert(cache_req && "Can't Find Instruction for Write!"); @@ -559,16 +558,16 @@ CacheUnit::write(DynInstPtr inst, T data, Addr addr, unsigned flags, // The block size of our peer unsigned blockSize = this->cachePort->peerBlockSize(); - //The size of the data we're trying to read. - int dataSize = sizeof(T); + //The size of the data we're trying to write. + int fullSize = size; + inst->totalSize = size; if (inst->traceData) { inst->traceData->setAddr(addr); - inst->traceData->setData(data); } if (inst->split2ndAccess) { - dataSize = inst->split2ndSize; + size = inst->split2ndSize; cache_req->splitAccess = true; cache_req->split2ndAccess = true; @@ -579,7 +578,7 @@ CacheUnit::write(DynInstPtr inst, T data, Addr addr, unsigned flags, //The address of the second part of this access if it needs to be split //across a cache line boundary. - Addr secondAddr = roundDown(addr + dataSize - 1, blockSize); + Addr secondAddr = roundDown(addr + size - 1, blockSize); if (secondAddr > addr && !inst->split2ndAccess) { @@ -589,7 +588,6 @@ CacheUnit::write(DynInstPtr inst, T data, Addr addr, unsigned flags, // Save All "Total" Split Information // ============================== inst->splitInst = true; - inst->splitTotalSize = dataSize; if (!inst->splitInstSked) { // Schedule Split Read/Complete for Instruction @@ -624,25 +622,25 @@ CacheUnit::write(DynInstPtr inst, T data, Addr addr, unsigned flags, // Split Information for First Access // ============================== - dataSize = secondAddr - addr; + size = secondAddr - addr; cache_req->splitAccess = true; // Split Information for Second Access // ============================== - inst->split2ndSize = addr + sizeof(T) - secondAddr; + inst->split2ndSize = addr + fullSize - secondAddr; inst->split2ndAddr = secondAddr; inst->split2ndStoreDataPtr = &cache_req->inst->storeData; - inst->split2ndStoreDataPtr += dataSize; + inst->split2ndStoreDataPtr += size; inst->split2ndFlags = flags; inst->splitInstSked = true; } - doTLBAccess(inst, cache_req, dataSize, flags, TheISA::TLB::Write); + doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Write); if (cache_req->fault == NoFault) { if (!cache_req->splitAccess) { // Remove this line since storeData is saved in INST? - cache_req->reqData = new uint8_t[dataSize]; + cache_req->reqData = new uint8_t[size]; doCacheAccess(inst, write_res); } else { doCacheAccess(inst, write_res, cache_req); @@ -729,8 +727,8 @@ CacheUnit::execute(int slot_num) cache_req->inst->split2ndAddr); inst->split2ndAccess = true; assert(inst->split2ndAddr != 0); - read(inst, inst->split2ndAddr, inst->split2ndData, - inst->split2ndFlags); + read(inst, inst->split2ndAddr, &inst->split2ndData, + inst->totalSize, inst->split2ndFlags); break; case InitSecondSplitWrite: @@ -741,8 +739,8 @@ CacheUnit::execute(int slot_num) inst->split2ndAccess = true; assert(inst->split2ndAddr != 0); - write(inst, inst->split2ndAddr, inst->split2ndData, - inst->split2ndFlags, NULL); + write(inst, &inst->split2ndData, inst->totalSize, + inst->split2ndAddr, inst->split2ndFlags, NULL); break; @@ -1075,7 +1073,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) if (inst->splitFinishCnt == 2) { cache_req->memReq->setVirt(0/*inst->tid*/, inst->getMemAddr(), - inst->splitTotalSize, + inst->totalSize, 0, 0); @@ -1301,113 +1299,3 @@ CacheUnit::squash(DynInstPtr inst, int stage_num, freeSlot(slot_remove_list[i]); } -// Extra Template Definitions -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, Twin32_t &data, unsigned flags); - -template -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, Twin64_t &data, unsigned flags); - -template -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, uint64_t &data, unsigned flags); - -template -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, uint32_t &data, unsigned flags); - -template -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, uint16_t &data, unsigned flags); - -template -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, uint8_t &data, unsigned flags); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, double &data, unsigned flags) -{ - return read(inst, addr, *(uint64_t*)&data, flags); -} - -template<> -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, float &data, unsigned flags) -{ - return read(inst, addr, *(uint32_t*)&data, flags); -} - - -template<> -Fault -CacheUnit::read(DynInstPtr inst, Addr addr, int32_t &data, unsigned flags) -{ - return read(inst, addr, (uint32_t&)data, flags); -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template -Fault -CacheUnit::write(DynInstPtr inst, Twin32_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -CacheUnit::write(DynInstPtr inst, Twin64_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -CacheUnit::write(DynInstPtr inst, uint64_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -CacheUnit::write(DynInstPtr inst, uint32_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -CacheUnit::write(DynInstPtr inst, uint16_t data, Addr addr, - unsigned flags, uint64_t *res); - -template -Fault -CacheUnit::write(DynInstPtr inst, uint8_t data, Addr addr, - unsigned flags, uint64_t *res); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -CacheUnit::write(DynInstPtr inst, double data, Addr addr, unsigned flags, - uint64_t *res) -{ - return write(inst, *(uint64_t*)&data, addr, flags, res); -} - -template<> -Fault -CacheUnit::write(DynInstPtr inst, float data, Addr addr, unsigned flags, - uint64_t *res) -{ - return write(inst, *(uint32_t*)&data, addr, flags, res); -} - - -template<> -Fault -CacheUnit::write(DynInstPtr inst, int32_t data, Addr addr, unsigned flags, - uint64_t *res) -{ - return write(inst, (uint32_t)data, addr, flags, res); -} - diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh index 177f81559..2f369db7c 100644 --- a/src/cpu/inorder/resources/cache_unit.hh +++ b/src/cpu/inorder/resources/cache_unit.hh @@ -161,12 +161,11 @@ class CacheUnit : public Resource /** Returns a specific port. */ Port *getPort(const std::string &if_name, int idx); - template <class T> - Fault read(DynInstPtr inst, Addr addr, T &data, unsigned flags); + Fault read(DynInstPtr inst, Addr addr, + uint8_t *data, unsigned size, unsigned flags); - template <class T> - Fault write(DynInstPtr inst, T data, Addr addr, unsigned flags, - uint64_t *res); + Fault write(DynInstPtr inst, uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *res); Fault doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size, int flags, TheISA::TLB::Mode tlb_mode); |