Deleted Added
sdiff udiff text old ( 9433:34971d2e0019 ) new ( 9442:36967173340c )
full compact
1/*
2 * Copyright (c) 2010-2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

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

89{
90 pkt = _pkt;
91 cpu->schedule(this, t);
92}
93
94TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p)
95 : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this),
96 dcachePort(this), ifetch_pkt(NULL), dcache_pkt(NULL), previousCycle(0),
97 fetchEvent(this), drainManager(NULL)
98{
99 _status = Idle;
100
101 system->totalNumInsts = 0;
102}
103
104
105TimingSimpleCPU::~TimingSimpleCPU()
106{
107}
108
109unsigned int
110TimingSimpleCPU::drain(DrainManager *drain_manager)
111{
112 if (_status == Idle ||
113 (_status == BaseSimpleCPU::Running && isDrained()) ||
114 _status == SwitchedOut) {
115 assert(!fetchEvent.scheduled());
116 DPRINTF(Drain, "No need to drain.\n");
117 return 0;
118 } else {
119 drainManager = drain_manager;
120 DPRINTF(Drain, "Requesting drain: %s\n", pcState());
121
122 // The fetch event can become descheduled if a drain didn't
123 // succeed on the first attempt. We need to reschedule it if
124 // the CPU is waiting for a microcode routine to complete.
125 if (_status == BaseSimpleCPU::Running && !isDrained() &&
126 !fetchEvent.scheduled()) {
127 schedule(fetchEvent, nextCycle());
128 }
129
130 return 1;
131 }
132}
133
134void
135TimingSimpleCPU::drainResume()
136{
137 assert(!fetchEvent.scheduled());
138
139 DPRINTF(SimpleCPU, "Resume\n");
140 if (_status != SwitchedOut && _status != Idle) {
141 if (system->getMemoryMode() != Enums::timing) {
142 fatal("The timing CPU requires the memory system to be in "
143 "'timing' mode.\n");
144 }
145
146 schedule(fetchEvent, nextCycle());
147 }
148}
149
150bool
151TimingSimpleCPU::tryCompleteDrain()
152{
153 if (!drainManager)
154 return false;
155
156 DPRINTF(Drain, "tryCompleteDrain: %s\n", pcState());
157 if (!isDrained())
158 return false;
159
160 DPRINTF(Drain, "CPU done draining, processing drain event\n");
161 drainManager->signalDrainDone();
162 drainManager = NULL;
163
164 return true;
165}
166
167void
168TimingSimpleCPU::switchOut()
169{
170 BaseSimpleCPU::switchOut();
171
172 assert(!fetchEvent.scheduled());
173 assert(_status == BaseSimpleCPU::Running || _status == Idle);
174 assert(!stayAtPC);
175 assert(microPC() == 0);
176
177 _status = SwitchedOut;
178 numCycles += curCycle() - previousCycle;
179}
180
181
182void
183TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
184{
185 BaseSimpleCPU::takeOverFrom(oldCPU);
186

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

342 if (traceData) {
343 // Since there was a fault, we shouldn't trace this instruction.
344 delete traceData;
345 traceData = NULL;
346 }
347
348 postExecute();
349
350 advanceInst(fault);
351}
352
353void
354TimingSimpleCPU::buildPacket(PacketPtr &pkt, RequestPtr req, bool read)
355{
356 MemCmd cmd;
357 if (read) {
358 cmd = MemCmd::ReadReq;

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

611 numCycles += curCycle() - previousCycle;
612 previousCycle = curCycle();
613}
614
615
616void
617TimingSimpleCPU::advanceInst(Fault fault)
618{
619 if (_status == Faulting)
620 return;
621
622 if (fault != NoFault) {
623 advancePC(fault);
624 DPRINTF(SimpleCPU, "Fault occured, scheduling fetch event\n");
625 reschedule(fetchEvent, nextCycle(), true);
626 _status = Faulting;
627 return;
628 }
629
630
631 if (!stayAtPC)
632 advancePC(fault);
633
634 if (tryCompleteDrain())
635 return;
636
637 if (_status == BaseSimpleCPU::Running) {
638 // kick off fetch of next instruction... callback from icache
639 // response will cause that instruction to be executed,
640 // keeping the CPU running.
641 fetch();
642 }
643}
644

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

655 assert(!pkt || !pkt->isError());
656 assert(_status == IcacheWaitResponse);
657
658 _status = BaseSimpleCPU::Running;
659
660 numCycles += curCycle() - previousCycle;
661 previousCycle = curCycle();
662
663 preExecute();
664 if (curStaticInst && curStaticInst->isMemRef()) {
665 // load or store: just send to dcache
666 Fault fault = curStaticInst->initiateAcc(this, traceData);
667
668 // If we're not running now the instruction will complete in a dcache
669 // response callback or the instruction faulted and has started an
670 // ifetch

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

801 TheISA::handleLockedRead(thread, pkt->req);
802 }
803
804 delete pkt->req;
805 delete pkt;
806
807 postExecute();
808
809 advanceInst(fault);
810}
811
812bool
813TimingSimpleCPU::DcachePort::recvTimingResp(PacketPtr pkt)
814{
815 // delay processing of returned data until next CPU clock edge
816 Tick next_tick = cpu->nextCycle();
817
818 if (next_tick == curTick()) {
819 cpu->completeDataAccess(pkt);

--- 105 unchanged lines hidden ---