summaryrefslogtreecommitdiff
path: root/src/cpu/inorder
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-08-13 06:16:02 -0700
committerGabe Black <gblack@eecs.umich.edu>2010-08-13 06:16:02 -0700
commitaa8c6e9c959eab4d516bc07593bea20ade9ad80c (patch)
tree3e0112e567da5dc1aa019f85458fbd9e37ad0cf2 /src/cpu/inorder
parent65dbcc6ea170e05ca2370a9a265a61668250fa98 (diff)
downloadgem5-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.cc122
-rw-r--r--src/cpu/inorder/cpu.hh9
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc35
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh7
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc170
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh9
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);