summaryrefslogtreecommitdiff
path: root/src/cpu/simple/timing.hh
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2008-11-09 21:56:28 -0800
committerGabe Black <gblack@eecs.umich.edu>2008-11-09 21:56:28 -0800
commit846cb450f985eb249a5fc50e97f9e643cb1ebfc5 (patch)
tree7bfb2783548995550bd7a33b23b0f56ae7e7e44b /src/cpu/simple/timing.hh
parent8c15518f30a5e7ffe0f82acde714c11000bc3714 (diff)
downloadgem5-846cb450f985eb249a5fc50e97f9e643cb1ebfc5.tar.xz
CPU: Make unaligned accesses work in the timing simple CPU.
Diffstat (limited to 'src/cpu/simple/timing.hh')
-rw-r--r--src/cpu/simple/timing.hh57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 0fc9b3152..b641b1302 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -49,6 +49,63 @@ class TimingSimpleCPU : public BaseSimpleCPU
private:
+ /*
+ * If an access needs to be broken into fragments, currently at most two,
+ * the the following two classes are used as the sender state of the
+ * packets so the CPU can keep track of everything. In the main packet
+ * sender state, there's an array with a spot for each fragment. If a
+ * fragment has already been accepted by the CPU, aka isn't waiting for
+ * a retry, it's pointer is NULL. After each fragment has successfully
+ * been processed, the "outstanding" counter is decremented. Once the
+ * count is zero, the entire larger access is complete.
+ */
+ class SplitMainSenderState : public Packet::SenderState
+ {
+ public:
+ int outstanding;
+ PacketPtr fragments[2];
+
+ SplitMainSenderState()
+ {
+ fragments[0] = NULL;
+ fragments[1] = NULL;
+ }
+
+ int
+ getPendingFragment()
+ {
+ if (fragments[0]) {
+ return 0;
+ } else if (fragments[1]) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+ };
+
+ class SplitFragmentSenderState : public Packet::SenderState
+ {
+ public:
+ SplitFragmentSenderState(PacketPtr _bigPkt, int _index) :
+ bigPkt(_bigPkt), index(_index)
+ {}
+ PacketPtr bigPkt;
+ int index;
+
+ void
+ clearFromParent()
+ {
+ SplitMainSenderState * main_send_state =
+ dynamic_cast<SplitMainSenderState *>(bigPkt->senderState);
+ main_send_state->fragments[index] = NULL;
+ }
+ };
+
+ bool handleReadPacket(PacketPtr pkt);
+ // This function always implicitly uses dcache_pkt.
+ bool handleWritePacket();
+
class CpuPort : public Port
{
protected: