summaryrefslogtreecommitdiff
path: root/src/cpu/simple
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/simple')
-rw-r--r--src/cpu/simple/timing.cc113
-rw-r--r--src/cpu/simple/timing.hh99
2 files changed, 72 insertions, 140 deletions
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 6b22d2fcf..db972d030 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -268,19 +268,9 @@ TimingSimpleCPU::handleReadPacket(PacketPtr pkt)
}
void
-TimingSimpleCPU::sendData(Fault fault, RequestPtr req,
- uint8_t *data, uint64_t *res, bool read)
+TimingSimpleCPU::sendData(RequestPtr req, uint8_t *data, uint64_t *res,
+ bool read)
{
- _status = Running;
- if (fault != NoFault) {
- if (req->isPrefetch())
- fault = NoFault;
- delete data;
- delete req;
-
- translationFault(fault);
- return;
- }
PacketPtr pkt;
buildPacket(pkt, req, read);
pkt->dataDynamic<uint8_t>(data);
@@ -311,25 +301,9 @@ TimingSimpleCPU::sendData(Fault fault, RequestPtr req,
}
void
-TimingSimpleCPU::sendSplitData(Fault fault1, Fault fault2,
- RequestPtr req1, RequestPtr req2, RequestPtr req,
- uint8_t *data, bool read)
+TimingSimpleCPU::sendSplitData(RequestPtr req1, RequestPtr req2,
+ RequestPtr req, uint8_t *data, bool read)
{
- _status = Running;
- if (fault1 != NoFault || fault2 != NoFault) {
- if (req1->isPrefetch())
- fault1 = NoFault;
- if (req2->isPrefetch())
- fault2 = NoFault;
- delete data;
- delete req1;
- delete req2;
- if (fault1 != NoFault)
- translationFault(fault1);
- else if (fault2 != NoFault)
- translationFault(fault2);
- return;
- }
PacketPtr pkt1, pkt2;
buildSplitPacket(pkt1, pkt2, req1, req2, req, data, read);
if (req->getFlags().isSet(Request::NO_ACCESS)) {
@@ -450,6 +424,7 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
const Addr pc = thread->readPC();
unsigned block_size = dcachePort.peerBlockSize();
int data_size = sizeof(T);
+ BaseTLB::Mode mode = BaseTLB::Read;
RequestPtr req = new Request(asid, addr, data_size,
flags, pc, _cpuId, tid);
@@ -457,24 +432,28 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
Addr split_addr = roundDown(addr + data_size - 1, block_size);
assert(split_addr <= addr || split_addr - addr < block_size);
-
_status = DTBWaitResponse;
if (split_addr > addr) {
RequestPtr req1, req2;
assert(!req->isLLSC() && !req->isSwap());
req->splitOnVaddr(split_addr, req1, req2);
- typedef SplitDataTranslation::WholeTranslationState WholeState;
- WholeState *state = new WholeState(req1, req2, req,
- (uint8_t *)(new T), BaseTLB::Read);
- thread->dtb->translateTiming(req1, tc,
- new SplitDataTranslation(this, 0, state), BaseTLB::Read);
- thread->dtb->translateTiming(req2, tc,
- new SplitDataTranslation(this, 1, state), BaseTLB::Read);
+ WholeTranslationState *state =
+ new WholeTranslationState(req, req1, req2, (uint8_t *)(new T),
+ NULL, mode);
+ DataTranslation<TimingSimpleCPU> *trans1 =
+ new DataTranslation<TimingSimpleCPU>(this, state, 0);
+ DataTranslation<TimingSimpleCPU> *trans2 =
+ new DataTranslation<TimingSimpleCPU>(this, state, 1);
+
+ thread->dtb->translateTiming(req1, tc, trans1, mode);
+ thread->dtb->translateTiming(req2, tc, trans2, mode);
} else {
- DataTranslation *translation =
- new DataTranslation(this, (uint8_t *)(new T), NULL, BaseTLB::Read);
- thread->dtb->translateTiming(req, tc, translation, BaseTLB::Read);
+ WholeTranslationState *state =
+ new WholeTranslationState(req, (uint8_t *)(new T), NULL, mode);
+ DataTranslation<TimingSimpleCPU> *translation
+ = new DataTranslation<TimingSimpleCPU>(this, state);
+ thread->dtb->translateTiming(req, tc, translation, mode);
}
if (traceData) {
@@ -568,6 +547,7 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
const Addr pc = thread->readPC();
unsigned block_size = dcachePort.peerBlockSize();
int data_size = sizeof(T);
+ BaseTLB::Mode mode = BaseTLB::Write;
RequestPtr req = new Request(asid, addr, data_size,
flags, pc, _cpuId, tid);
@@ -583,17 +563,22 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
assert(!req->isLLSC() && !req->isSwap());
req->splitOnVaddr(split_addr, req1, req2);
- typedef SplitDataTranslation::WholeTranslationState WholeState;
- WholeState *state = new WholeState(req1, req2, req,
- (uint8_t *)dataP, BaseTLB::Write);
- thread->dtb->translateTiming(req1, tc,
- new SplitDataTranslation(this, 0, state), BaseTLB::Write);
- thread->dtb->translateTiming(req2, tc,
- new SplitDataTranslation(this, 1, state), BaseTLB::Write);
+ WholeTranslationState *state =
+ new WholeTranslationState(req, req1, req2, (uint8_t *)dataP,
+ res, mode);
+ DataTranslation<TimingSimpleCPU> *trans1 =
+ new DataTranslation<TimingSimpleCPU>(this, state, 0);
+ DataTranslation<TimingSimpleCPU> *trans2 =
+ new DataTranslation<TimingSimpleCPU>(this, state, 1);
+
+ thread->dtb->translateTiming(req1, tc, trans1, mode);
+ thread->dtb->translateTiming(req2, tc, trans2, mode);
} else {
- DataTranslation *translation =
- new DataTranslation(this, (uint8_t *)dataP, res, BaseTLB::Write);
- thread->dtb->translateTiming(req, tc, translation, BaseTLB::Write);
+ WholeTranslationState *state =
+ new WholeTranslationState(req, (uint8_t *)dataP, res, mode);
+ DataTranslation<TimingSimpleCPU> *translation =
+ new DataTranslation<TimingSimpleCPU>(this, state);
+ thread->dtb->translateTiming(req, tc, translation, mode);
}
if (traceData) {
@@ -668,6 +653,32 @@ TimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
void
+TimingSimpleCPU::finishTranslation(WholeTranslationState *state)
+{
+ _status = Running;
+
+ if (state->getFault() != NoFault) {
+ if (state->isPrefetch()) {
+ state->setNoFault();
+ }
+ delete state->data;
+ state->deleteReqs();
+ translationFault(state->getFault());
+ } else {
+ if (!state->isSplit) {
+ sendData(state->mainReq, state->data, state->res,
+ state->mode == BaseTLB::Read);
+ } else {
+ sendSplitData(state->sreqLow, state->sreqHigh, state->mainReq,
+ state->data, state->mode == BaseTLB::Read);
+ }
+ }
+
+ delete state;
+}
+
+
+void
TimingSimpleCPU::fetch()
{
DPRINTF(SimpleCPU, "Fetch\n");
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 6f6b02bb7..62c105418 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -32,6 +32,7 @@
#define __CPU_SIMPLE_TIMING_HH__
#include "cpu/simple/base.hh"
+#include "cpu/translation.hh"
#include "params/TimingSimpleCPU.hh"
@@ -115,95 +116,9 @@ class TimingSimpleCPU : public BaseSimpleCPU
};
FetchTranslation fetchTranslation;
- class DataTranslation : public BaseTLB::Translation
- {
- protected:
- TimingSimpleCPU *cpu;
- uint8_t *data;
- uint64_t *res;
- BaseTLB::Mode mode;
-
- public:
- DataTranslation(TimingSimpleCPU *_cpu,
- 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,
- BaseTLB::Mode mode)
- {
- assert(mode == this->mode);
- cpu->sendData(fault, req, data, res, mode == BaseTLB::Read);
- delete this;
- }
- };
-
- class SplitDataTranslation : public BaseTLB::Translation
- {
- public:
- struct WholeTranslationState
- {
- public:
- int outstanding;
- RequestPtr requests[2];
- RequestPtr mainReq;
- Fault faults[2];
- uint8_t *data;
- BaseTLB::Mode mode;
-
- WholeTranslationState(RequestPtr req1, RequestPtr req2,
- 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;
- this->data = data;
- this->mode = mode;
- }
- };
-
- TimingSimpleCPU *cpu;
- int index;
- WholeTranslationState *state;
-
- SplitDataTranslation(TimingSimpleCPU *_cpu, int _index,
- WholeTranslationState *_state)
- : cpu(_cpu), index(_index), state(_state)
- {}
-
- void
- finish(Fault fault, RequestPtr req, ThreadContext *tc,
- BaseTLB::Mode mode)
- {
- assert(state);
- assert(state->outstanding);
- state->faults[index] = fault;
- if (--state->outstanding == 0) {
- cpu->sendSplitData(state->faults[0],
- state->faults[1],
- state->requests[0],
- state->requests[1],
- state->mainReq,
- state->data,
- state->mode == BaseTLB::Read);
- delete state;
- }
- delete this;
- }
- };
-
- void sendData(Fault fault, RequestPtr req,
- uint8_t *data, uint64_t *res, bool read);
- void sendSplitData(Fault fault1, Fault fault2,
- RequestPtr req1, RequestPtr req2, RequestPtr req,
- uint8_t *data, bool read);
+ void sendData(RequestPtr req, uint8_t *data, uint64_t *res, bool read);
+ void sendSplitData(RequestPtr req1, RequestPtr req2, RequestPtr req,
+ uint8_t *data, bool read);
void translationFault(Fault fault);
@@ -351,6 +266,12 @@ class TimingSimpleCPU : public BaseSimpleCPU
*/
void printAddr(Addr a);
+ /**
+ * Finish a DTB translation.
+ * @param state The DTB translation state.
+ */
+ void finishTranslation(WholeTranslationState *state);
+
private:
typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent;