lsq_unit_impl.hh (2674:6d4afef73a20) lsq_unit_impl.hh (2678:1f86b91dc3bb)
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 18 unchanged lines hidden (view full) ---

27 */
28
29#include "cpu/checker/cpu.hh"
30#include "cpu/o3/lsq_unit.hh"
31#include "base/str.hh"
32#include "mem/request.hh"
33
34template<class Impl>
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 18 unchanged lines hidden (view full) ---

27 */
28
29#include "cpu/checker/cpu.hh"
30#include "cpu/o3/lsq_unit.hh"
31#include "base/str.hh"
32#include "mem/request.hh"
33
34template<class Impl>
35void
36LSQUnit<Impl>::completeDataAccess(PacketPtr pkt)
35LSQUnit<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt,
36 LSQUnit *lsq_ptr)
37 : Event(&mainEventQueue), inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
37{
38{
38/*
39 DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum);
40 DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum);
39 this->setFlags(Event::AutoDelete);
40}
41
41
42 //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
43
44 if (iewStage->isSwitchedOut()) {
45 inst = NULL;
46 return;
47 } else if (inst->isSquashed()) {
48 iewStage->wakeCPU();
49 inst = NULL;
50 return;
42template<class Impl>
43void
44LSQUnit<Impl>::WritebackEvent::process()
45{
46 if (!lsqPtr->isSwitchedOut()) {
47 lsqPtr->writeback(inst, pkt);
51 }
48 }
49 delete pkt;
50}
52
51
53 iewStage->wakeCPU();
54
55 if (!inst->isExecuted()) {
56 inst->setExecuted();
57
58 // Complete access to copy data to proper place.
59 inst->completeAcc();
60 }
61
62 // Need to insert instruction into queue to commit
63 iewStage->instToCommit(inst);
64
65 iewStage->activityThisCycle();
66
67 inst = NULL;
68*/
52template<class Impl>
53const char *
54LSQUnit<Impl>::WritebackEvent::description()
55{
56 return "Store writeback event";
69}
70
71template<class Impl>
72void
57}
58
59template<class Impl>
60void
73LSQUnit<Impl>::completeStoreDataAccess(DynInstPtr &inst)
61LSQUnit<Impl>::completeDataAccess(PacketPtr pkt)
74{
62{
75/*
76 DPRINTF(LSQ, "Cache miss complete for store idx:%i\n", storeIdx);
77 DPRINTF(Activity, "Activity: st writeback event idx:%i\n", storeIdx);
63 LSQSenderState *state = dynamic_cast<LSQSenderState *>(pkt->senderState);
64 DynInstPtr inst = state->inst;
65 DPRINTF(IEW, "Writeback event [sn:%lli]\n", inst->seqNum);
66// DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum);
78
67
79 //lsqPtr->removeMSHR(lsqPtr->storeQueue[storeIdx].inst->seqNum);
68 //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
80
69
81 if (lsqPtr->isSwitchedOut()) {
82 if (wbEvent)
83 delete wbEvent;
84
70 if (isSwitchedOut() || inst->isSquashed()) {
71 delete state;
72 delete pkt;
85 return;
73 return;
74 } else {
75 if (!state->noWB) {
76 writeback(inst, pkt);
77 }
78
79 if (inst->isStore()) {
80 completeStore(state->idx);
81 }
86 }
87
82 }
83
88 lsqPtr->cpu->wakeCPU();
89
90 if (wb)
91 lsqPtr->completeDataAccess(storeIdx);
92 lsqPtr->completeStore(storeIdx);
93*/
84 delete state;
85 delete pkt;
94}
95
96template <class Impl>
97Tick
98LSQUnit<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
99{
100 panic("O3CPU model does not work with atomic mode!");
101 return curTick;

--- 39 unchanged lines hidden (view full) ---

141 cpu->_status = DcacheWaitResponse;
142 cpu->dcache_pkt = NULL;
143 }
144*/
145}
146
147template <class Impl>
148LSQUnit<Impl>::LSQUnit()
86}
87
88template <class Impl>
89Tick
90LSQUnit<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
91{
92 panic("O3CPU model does not work with atomic mode!");
93 return curTick;

--- 39 unchanged lines hidden (view full) ---

133 cpu->_status = DcacheWaitResponse;
134 cpu->dcache_pkt = NULL;
135 }
136*/
137}
138
139template <class Impl>
140LSQUnit<Impl>::LSQUnit()
149 : loads(0), stores(0), storesToWB(0), stalled(false), isLoadBlocked(false),
141 : loads(0), stores(0), storesToWB(0), stalled(false),
142 isStoreBlocked(false), isLoadBlocked(false),
150 loadBlockedHandled(false)
151{
152}
153
154template<class Impl>
155void
156LSQUnit<Impl>::init(Params *params, unsigned maxLQEntries,
157 unsigned maxSQEntries, unsigned id)

--- 13 unchanged lines hidden (view full) ---

171
172 loadHead = loadTail = 0;
173
174 storeHead = storeWBIdx = storeTail = 0;
175
176 usedPorts = 0;
177 cachePorts = params->cachePorts;
178
143 loadBlockedHandled(false)
144{
145}
146
147template<class Impl>
148void
149LSQUnit<Impl>::init(Params *params, unsigned maxLQEntries,
150 unsigned maxSQEntries, unsigned id)

--- 13 unchanged lines hidden (view full) ---

164
165 loadHead = loadTail = 0;
166
167 storeHead = storeWBIdx = storeTail = 0;
168
169 usedPorts = 0;
170 cachePorts = params->cachePorts;
171
179 Port *mem_dport = params->mem->getPort("");
180 dcachePort->setPeer(mem_dport);
181 mem_dport->setPeer(dcachePort);
172 mem = params->mem;
182
183 memDepViolator = NULL;
184
185 blockedLoadSeqNum = 0;
186}
187
188template<class Impl>
189void
190LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr)
191{
192 cpu = cpu_ptr;
193 dcachePort = new DcachePort(cpu, this);
173
174 memDepViolator = NULL;
175
176 blockedLoadSeqNum = 0;
177}
178
179template<class Impl>
180void
181LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr)
182{
183 cpu = cpu_ptr;
184 dcachePort = new DcachePort(cpu, this);
185
186 Port *mem_dport = mem->getPort("");
187 dcachePort->setPeer(mem_dport);
188 mem_dport->setPeer(dcachePort);
194}
195
196template<class Impl>
197std::string
198LSQUnit<Impl>::name() const
199{
200 if (Impl::MaxThreads == 1) {
201 return iewStage->name() + ".lsq";

--- 239 unchanged lines hidden (view full) ---

441 DPRINTF(LSQUnit, "Executing store PC %#x [sn:%lli]\n",
442 store_inst->readPC(), store_inst->seqNum);
443
444 // Check the recently completed loads to see if any match this store's
445 // address. If so, then we have a memory ordering violation.
446 int load_idx = store_inst->lqIdx;
447
448 Fault store_fault = store_inst->initiateAcc();
189}
190
191template<class Impl>
192std::string
193LSQUnit<Impl>::name() const
194{
195 if (Impl::MaxThreads == 1) {
196 return iewStage->name() + ".lsq";

--- 239 unchanged lines hidden (view full) ---

436 DPRINTF(LSQUnit, "Executing store PC %#x [sn:%lli]\n",
437 store_inst->readPC(), store_inst->seqNum);
438
439 // Check the recently completed loads to see if any match this store's
440 // address. If so, then we have a memory ordering violation.
441 int load_idx = store_inst->lqIdx;
442
443 Fault store_fault = store_inst->initiateAcc();
449// Fault store_fault = store_inst->execute();
450
451 if (storeQueue[store_idx].size == 0) {
452 DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n",
453 store_inst->readPC(),store_inst->seqNum);
454
455 return store_fault;
456 }
457

--- 99 unchanged lines hidden (view full) ---

557LSQUnit<Impl>::writebackStores()
558{
559 while (storesToWB > 0 &&
560 storeWBIdx != storeTail &&
561 storeQueue[storeWBIdx].inst &&
562 storeQueue[storeWBIdx].canWB &&
563 usedPorts < cachePorts) {
564
444
445 if (storeQueue[store_idx].size == 0) {
446 DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n",
447 store_inst->readPC(),store_inst->seqNum);
448
449 return store_fault;
450 }
451

--- 99 unchanged lines hidden (view full) ---

551LSQUnit<Impl>::writebackStores()
552{
553 while (storesToWB > 0 &&
554 storeWBIdx != storeTail &&
555 storeQueue[storeWBIdx].inst &&
556 storeQueue[storeWBIdx].canWB &&
557 usedPorts < cachePorts) {
558
559 if (isStoreBlocked) {
560 DPRINTF(LSQUnit, "Unable to write back any more stores, cache"
561 " is blocked!\n");
562 break;
563 }
564
565 // Store didn't write any data so no need to write it back to
566 // memory.
567 if (storeQueue[storeWBIdx].size == 0) {
568 completeStore(storeWBIdx);
569
570 incrStIdx(storeWBIdx);
571
572 continue;
573 }
565 // Store didn't write any data so no need to write it back to
566 // memory.
567 if (storeQueue[storeWBIdx].size == 0) {
568 completeStore(storeWBIdx);
569
570 incrStIdx(storeWBIdx);
571
572 continue;
573 }
574/*
575 if (dcacheInterface && dcacheInterface->isBlocked()) {
576 DPRINTF(LSQUnit, "Unable to write back any more stores, cache"
577 " is blocked!\n");
578 break;
579 }
580*/
574
581 ++usedPorts;
582
583 if (storeQueue[storeWBIdx].inst->isDataPrefetch()) {
584 incrStIdx(storeWBIdx);
585
586 continue;
587 }
588
589 assert(storeQueue[storeWBIdx].req);
590 assert(!storeQueue[storeWBIdx].committed);
591
592 DynInstPtr inst = storeQueue[storeWBIdx].inst;
593
594 Request *req = storeQueue[storeWBIdx].req;
595 storeQueue[storeWBIdx].committed = true;
596
597 assert(!inst->memData);
598 inst->memData = new uint8_t[64];
575 ++usedPorts;
576
577 if (storeQueue[storeWBIdx].inst->isDataPrefetch()) {
578 incrStIdx(storeWBIdx);
579
580 continue;
581 }
582
583 assert(storeQueue[storeWBIdx].req);
584 assert(!storeQueue[storeWBIdx].committed);
585
586 DynInstPtr inst = storeQueue[storeWBIdx].inst;
587
588 Request *req = storeQueue[storeWBIdx].req;
589 storeQueue[storeWBIdx].committed = true;
590
591 assert(!inst->memData);
592 inst->memData = new uint8_t[64];
599 memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data, req->getSize());
593 memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data,
594 req->getSize());
600
601 PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
602 data_pkt->dataStatic(inst->memData);
603
595
596 PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
597 data_pkt->dataStatic(inst->memData);
598
599 LSQSenderState *state = new LSQSenderState;
600 state->isLoad = false;
601 state->idx = storeWBIdx;
602 state->inst = inst;
603 data_pkt->senderState = state;
604
604 DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x "
605 "to Addr:%#x, data:%#x [sn:%lli]\n",
606 storeWBIdx, storeQueue[storeWBIdx].inst->readPC(),
607 req->getPaddr(), *(inst->memData),
608 storeQueue[storeWBIdx].inst->seqNum);
609
610 if (!dcachePort->sendTiming(data_pkt)) {
611 // Need to handle becoming blocked on a store.
605 DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x "
606 "to Addr:%#x, data:%#x [sn:%lli]\n",
607 storeWBIdx, storeQueue[storeWBIdx].inst->readPC(),
608 req->getPaddr(), *(inst->memData),
609 storeQueue[storeWBIdx].inst->seqNum);
610
611 if (!dcachePort->sendTiming(data_pkt)) {
612 // Need to handle becoming blocked on a store.
613 isStoreBlocked = true;
612 } else {
614 } else {
613 /*
614 StoreCompletionEvent *store_event = new
615 StoreCompletionEvent(storeWBIdx, NULL, this);
616 */
617 if (isStalled() &&
618 storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
619 DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
620 "load idx:%i\n",
621 stallingStoreIsn, stallingLoadIdx);
622 stalled = false;
623 stallingStoreIsn = 0;
624 iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
625 }
615 if (isStalled() &&
616 storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
617 DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
618 "load idx:%i\n",
619 stallingStoreIsn, stallingLoadIdx);
620 stalled = false;
621 stallingStoreIsn = 0;
622 iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
623 }
626/*
627 typename LdWritebackEvent *wb = NULL;
628 if (req->flags & LOCKED) {
629 // Stx_C should not generate a system port transaction
630 // if it misses in the cache, but that might be hard
631 // to accomplish without explicit cache support.
632 wb = new typename
633 LdWritebackEvent(storeQueue[storeWBIdx].inst,
634 iewStage);
635 store_event->wbEvent = wb;
624
625 if (!(req->getFlags() & LOCKED)) {
626 assert(!storeQueue[storeWBIdx].inst->isStoreConditional());
627 // Non-store conditionals do not need a writeback.
628 state->noWB = true;
636 }
629 }
637*/
630
638 if (data_pkt->result != Packet::Success) {
639 DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
640 storeWBIdx);
641
642 DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
643 storeQueue[storeWBIdx].inst->seqNum);
644
645 //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);

--- 110 unchanged lines hidden (view full) ---

756 storeTail = store_idx;
757
758 decrStIdx(store_idx);
759 }
760}
761
762template <class Impl>
763void
631 if (data_pkt->result != Packet::Success) {
632 DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
633 storeWBIdx);
634
635 DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
636 storeQueue[storeWBIdx].inst->seqNum);
637
638 //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);

--- 110 unchanged lines hidden (view full) ---

749 storeTail = store_idx;
750
751 decrStIdx(store_idx);
752 }
753}
754
755template <class Impl>
756void
757LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
758{
759 iewStage->wakeCPU();
760
761 // Squashed instructions do not need to complete their access.
762 if (inst->isSquashed()) {
763 assert(!inst->isStore());
764 return;
765 }
766
767 if (!inst->isExecuted()) {
768 inst->setExecuted();
769
770 // Complete access to copy data to proper place.
771 inst->completeAcc(pkt);
772 }
773
774 // Need to insert instruction into queue to commit
775 iewStage->instToCommit(inst);
776
777 iewStage->activityThisCycle();
778}
779
780template <class Impl>
781void
764LSQUnit<Impl>::completeStore(int store_idx)
765{
766 assert(storeQueue[store_idx].inst);
767 storeQueue[store_idx].completed = true;
768 --storesToWB;
769 // A bit conservative because a store completion may not free up entries,
770 // but hopefully avoids two store completions in one cycle from making
771 // the CPU tick twice.

--- 98 unchanged lines hidden ---
782LSQUnit<Impl>::completeStore(int store_idx)
783{
784 assert(storeQueue[store_idx].inst);
785 storeQueue[store_idx].completed = true;
786 --storesToWB;
787 // A bit conservative because a store completion may not free up entries,
788 // but hopefully avoids two store completions in one cycle from making
789 // the CPU tick twice.

--- 98 unchanged lines hidden ---