base.cc (7725:00ea9430643b) base.cc (7823:dac01f14f20f)
1/*
2 * Copyright (c) 2010 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Steve Reinhardt
41 */
42
43#include "arch/faults.hh"
44#include "arch/utility.hh"
45#include "base/cp_annotate.hh"
46#include "base/cprintf.hh"
47#include "base/inifile.hh"
48#include "base/loader/symtab.hh"
49#include "base/misc.hh"
50#include "base/pollevent.hh"
51#include "base/range.hh"
52#include "base/trace.hh"
53#include "base/types.hh"
54#include "config/the_isa.hh"
55#include "cpu/base.hh"
56#include "cpu/exetrace.hh"
57#include "cpu/profile.hh"
58#include "cpu/simple/base.hh"
59#include "cpu/simple_thread.hh"
60#include "cpu/smt.hh"
61#include "cpu/static_inst.hh"
62#include "cpu/thread_context.hh"
63#include "mem/packet.hh"
64#include "mem/request.hh"
65#include "params/BaseSimpleCPU.hh"
66#include "sim/byteswap.hh"
67#include "sim/debug.hh"
68#include "sim/sim_events.hh"
69#include "sim/sim_object.hh"
70#include "sim/stats.hh"
71#include "sim/system.hh"
72
73#if FULL_SYSTEM
74#include "arch/kernel_stats.hh"
75#include "arch/stacktrace.hh"
76#include "arch/tlb.hh"
77#include "arch/vtophys.hh"
78#else // !FULL_SYSTEM
79#include "mem/mem_object.hh"
80#endif // FULL_SYSTEM
81
82using namespace std;
83using namespace TheISA;
84
85BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
86 : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
87{
88#if FULL_SYSTEM
89 thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
90#else
91 thread = new SimpleThread(this, /* thread_num */ 0, p->workload[0],
92 p->itb, p->dtb);
93#endif // !FULL_SYSTEM
94
95 thread->setStatus(ThreadContext::Halted);
96
97 tc = thread->getTC();
98
99 numInst = 0;
100 startNumInst = 0;
101 numLoad = 0;
102 startNumLoad = 0;
103 lastIcacheStall = 0;
104 lastDcacheStall = 0;
105
106 threadContexts.push_back(tc);
107
108
109 fetchOffset = 0;
110 stayAtPC = false;
111}
112
113BaseSimpleCPU::~BaseSimpleCPU()
114{
115}
116
117void
118BaseSimpleCPU::deallocateContext(int thread_num)
119{
120 // for now, these are equivalent
121 suspendContext(thread_num);
122}
123
124
125void
126BaseSimpleCPU::haltContext(int thread_num)
127{
128 // for now, these are equivalent
129 suspendContext(thread_num);
130}
131
132
133void
134BaseSimpleCPU::regStats()
135{
136 using namespace Stats;
137
138 BaseCPU::regStats();
139
140 numInsts
141 .name(name() + ".num_insts")
142 .desc("Number of instructions executed")
143 ;
144
145 numMemRefs
146 .name(name() + ".num_refs")
147 .desc("Number of memory references")
148 ;
149
150 notIdleFraction
151 .name(name() + ".not_idle_fraction")
152 .desc("Percentage of non-idle cycles")
153 ;
154
155 idleFraction
156 .name(name() + ".idle_fraction")
157 .desc("Percentage of idle cycles")
158 ;
159
160 icacheStallCycles
161 .name(name() + ".icache_stall_cycles")
162 .desc("ICache total stall cycles")
163 .prereq(icacheStallCycles)
164 ;
165
166 dcacheStallCycles
167 .name(name() + ".dcache_stall_cycles")
168 .desc("DCache total stall cycles")
169 .prereq(dcacheStallCycles)
170 ;
171
172 icacheRetryCycles
173 .name(name() + ".icache_retry_cycles")
174 .desc("ICache total retry cycles")
175 .prereq(icacheRetryCycles)
176 ;
177
178 dcacheRetryCycles
179 .name(name() + ".dcache_retry_cycles")
180 .desc("DCache total retry cycles")
181 .prereq(dcacheRetryCycles)
182 ;
183
184 idleFraction = constant(1.0) - notIdleFraction;
185}
186
187void
188BaseSimpleCPU::resetStats()
189{
190// startNumInst = numInst;
191 notIdleFraction = (_status != Idle);
192}
193
194void
195BaseSimpleCPU::serialize(ostream &os)
196{
197 SERIALIZE_ENUM(_status);
198 BaseCPU::serialize(os);
199// SERIALIZE_SCALAR(inst);
200 nameOut(os, csprintf("%s.xc.0", name()));
201 thread->serialize(os);
202}
203
204void
205BaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
206{
207 UNSERIALIZE_ENUM(_status);
208 BaseCPU::unserialize(cp, section);
209// UNSERIALIZE_SCALAR(inst);
210 thread->unserialize(cp, csprintf("%s.xc.0", section));
211}
212
213void
214change_thread_state(ThreadID tid, int activate, int priority)
215{
216}
217
218#if FULL_SYSTEM
219Addr
220BaseSimpleCPU::dbg_vtophys(Addr addr)
221{
222 return vtophys(tc, addr);
223}
224#endif // FULL_SYSTEM
225
226#if FULL_SYSTEM
227void
228BaseSimpleCPU::wakeup()
229{
230 if (thread->status() != ThreadContext::Suspended)
231 return;
232
233 DPRINTF(Quiesce,"Suspended Processor awoke\n");
234 thread->activate();
235}
236#endif // FULL_SYSTEM
237
238void
239BaseSimpleCPU::checkForInterrupts()
240{
241#if FULL_SYSTEM
242 if (checkInterrupts(tc)) {
243 Fault interrupt = interrupts->getInterrupt(tc);
244
245 if (interrupt != NoFault) {
246 fetchOffset = 0;
247 interrupts->updateIntrInfo(tc);
248 interrupt->invoke(tc);
249 predecoder.reset();
250 }
251 }
252#endif
253}
254
255
256void
257BaseSimpleCPU::setupFetchRequest(Request *req)
258{
259 Addr instAddr = thread->instAddr();
260
261 // set up memory request for instruction fetch
262 DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr);
263
264 Addr fetchPC = (instAddr & PCMask) + fetchOffset;
265 req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instAddr);
266}
267
268
269void
270BaseSimpleCPU::preExecute()
271{
272 // maintain $r0 semantics
273 thread->setIntReg(ZeroReg, 0);
274#if THE_ISA == ALPHA_ISA
275 thread->setFloatReg(ZeroReg, 0.0);
276#endif // ALPHA_ISA
277
278 // check for instruction-count-based events
279 comInstEventQueue[0]->serviceEvents(numInst);
280
281 // decode the instruction
282 inst = gtoh(inst);
283
284 TheISA::PCState pcState = thread->pcState();
285
286 if (isRomMicroPC(pcState.microPC())) {
287 stayAtPC = false;
288 curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
289 curMacroStaticInst);
290 } else if (!curMacroStaticInst) {
291 //We're not in the middle of a macro instruction
292 StaticInstPtr instPtr = NULL;
293
294 //Predecode, ie bundle up an ExtMachInst
295 //This should go away once the constructor can be set up properly
296 predecoder.setTC(thread->getTC());
297 //If more fetch data is needed, pass it in.
298 Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
299 //if(predecoder.needMoreBytes())
300 predecoder.moreBytes(pcState, fetchPC, inst);
301 //else
302 // predecoder.process();
303
304 //If an instruction is ready, decode it. Otherwise, we'll have to
305 //fetch beyond the MachInst at the current pc.
306 if (predecoder.extMachInstReady()) {
307 stayAtPC = false;
308 ExtMachInst machInst = predecoder.getExtMachInst(pcState);
309 thread->pcState(pcState);
310 instPtr = StaticInst::decode(machInst, pcState.instAddr());
311 } else {
312 stayAtPC = true;
313 fetchOffset += sizeof(MachInst);
314 }
315
316 //If we decoded an instruction and it's microcoded, start pulling
317 //out micro ops
318 if (instPtr && instPtr->isMacroop()) {
319 curMacroStaticInst = instPtr;
320 curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
321 } else {
322 curStaticInst = instPtr;
323 }
324 } else {
325 //Read the next micro op from the macro op
326 curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
327 }
328
329 //If we decoded an instruction this "tick", record information about it.
330 if(curStaticInst)
331 {
332#if TRACING_ON
1/*
2 * Copyright (c) 2010 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Steve Reinhardt
41 */
42
43#include "arch/faults.hh"
44#include "arch/utility.hh"
45#include "base/cp_annotate.hh"
46#include "base/cprintf.hh"
47#include "base/inifile.hh"
48#include "base/loader/symtab.hh"
49#include "base/misc.hh"
50#include "base/pollevent.hh"
51#include "base/range.hh"
52#include "base/trace.hh"
53#include "base/types.hh"
54#include "config/the_isa.hh"
55#include "cpu/base.hh"
56#include "cpu/exetrace.hh"
57#include "cpu/profile.hh"
58#include "cpu/simple/base.hh"
59#include "cpu/simple_thread.hh"
60#include "cpu/smt.hh"
61#include "cpu/static_inst.hh"
62#include "cpu/thread_context.hh"
63#include "mem/packet.hh"
64#include "mem/request.hh"
65#include "params/BaseSimpleCPU.hh"
66#include "sim/byteswap.hh"
67#include "sim/debug.hh"
68#include "sim/sim_events.hh"
69#include "sim/sim_object.hh"
70#include "sim/stats.hh"
71#include "sim/system.hh"
72
73#if FULL_SYSTEM
74#include "arch/kernel_stats.hh"
75#include "arch/stacktrace.hh"
76#include "arch/tlb.hh"
77#include "arch/vtophys.hh"
78#else // !FULL_SYSTEM
79#include "mem/mem_object.hh"
80#endif // FULL_SYSTEM
81
82using namespace std;
83using namespace TheISA;
84
85BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
86 : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
87{
88#if FULL_SYSTEM
89 thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
90#else
91 thread = new SimpleThread(this, /* thread_num */ 0, p->workload[0],
92 p->itb, p->dtb);
93#endif // !FULL_SYSTEM
94
95 thread->setStatus(ThreadContext::Halted);
96
97 tc = thread->getTC();
98
99 numInst = 0;
100 startNumInst = 0;
101 numLoad = 0;
102 startNumLoad = 0;
103 lastIcacheStall = 0;
104 lastDcacheStall = 0;
105
106 threadContexts.push_back(tc);
107
108
109 fetchOffset = 0;
110 stayAtPC = false;
111}
112
113BaseSimpleCPU::~BaseSimpleCPU()
114{
115}
116
117void
118BaseSimpleCPU::deallocateContext(int thread_num)
119{
120 // for now, these are equivalent
121 suspendContext(thread_num);
122}
123
124
125void
126BaseSimpleCPU::haltContext(int thread_num)
127{
128 // for now, these are equivalent
129 suspendContext(thread_num);
130}
131
132
133void
134BaseSimpleCPU::regStats()
135{
136 using namespace Stats;
137
138 BaseCPU::regStats();
139
140 numInsts
141 .name(name() + ".num_insts")
142 .desc("Number of instructions executed")
143 ;
144
145 numMemRefs
146 .name(name() + ".num_refs")
147 .desc("Number of memory references")
148 ;
149
150 notIdleFraction
151 .name(name() + ".not_idle_fraction")
152 .desc("Percentage of non-idle cycles")
153 ;
154
155 idleFraction
156 .name(name() + ".idle_fraction")
157 .desc("Percentage of idle cycles")
158 ;
159
160 icacheStallCycles
161 .name(name() + ".icache_stall_cycles")
162 .desc("ICache total stall cycles")
163 .prereq(icacheStallCycles)
164 ;
165
166 dcacheStallCycles
167 .name(name() + ".dcache_stall_cycles")
168 .desc("DCache total stall cycles")
169 .prereq(dcacheStallCycles)
170 ;
171
172 icacheRetryCycles
173 .name(name() + ".icache_retry_cycles")
174 .desc("ICache total retry cycles")
175 .prereq(icacheRetryCycles)
176 ;
177
178 dcacheRetryCycles
179 .name(name() + ".dcache_retry_cycles")
180 .desc("DCache total retry cycles")
181 .prereq(dcacheRetryCycles)
182 ;
183
184 idleFraction = constant(1.0) - notIdleFraction;
185}
186
187void
188BaseSimpleCPU::resetStats()
189{
190// startNumInst = numInst;
191 notIdleFraction = (_status != Idle);
192}
193
194void
195BaseSimpleCPU::serialize(ostream &os)
196{
197 SERIALIZE_ENUM(_status);
198 BaseCPU::serialize(os);
199// SERIALIZE_SCALAR(inst);
200 nameOut(os, csprintf("%s.xc.0", name()));
201 thread->serialize(os);
202}
203
204void
205BaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
206{
207 UNSERIALIZE_ENUM(_status);
208 BaseCPU::unserialize(cp, section);
209// UNSERIALIZE_SCALAR(inst);
210 thread->unserialize(cp, csprintf("%s.xc.0", section));
211}
212
213void
214change_thread_state(ThreadID tid, int activate, int priority)
215{
216}
217
218#if FULL_SYSTEM
219Addr
220BaseSimpleCPU::dbg_vtophys(Addr addr)
221{
222 return vtophys(tc, addr);
223}
224#endif // FULL_SYSTEM
225
226#if FULL_SYSTEM
227void
228BaseSimpleCPU::wakeup()
229{
230 if (thread->status() != ThreadContext::Suspended)
231 return;
232
233 DPRINTF(Quiesce,"Suspended Processor awoke\n");
234 thread->activate();
235}
236#endif // FULL_SYSTEM
237
238void
239BaseSimpleCPU::checkForInterrupts()
240{
241#if FULL_SYSTEM
242 if (checkInterrupts(tc)) {
243 Fault interrupt = interrupts->getInterrupt(tc);
244
245 if (interrupt != NoFault) {
246 fetchOffset = 0;
247 interrupts->updateIntrInfo(tc);
248 interrupt->invoke(tc);
249 predecoder.reset();
250 }
251 }
252#endif
253}
254
255
256void
257BaseSimpleCPU::setupFetchRequest(Request *req)
258{
259 Addr instAddr = thread->instAddr();
260
261 // set up memory request for instruction fetch
262 DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr);
263
264 Addr fetchPC = (instAddr & PCMask) + fetchOffset;
265 req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instAddr);
266}
267
268
269void
270BaseSimpleCPU::preExecute()
271{
272 // maintain $r0 semantics
273 thread->setIntReg(ZeroReg, 0);
274#if THE_ISA == ALPHA_ISA
275 thread->setFloatReg(ZeroReg, 0.0);
276#endif // ALPHA_ISA
277
278 // check for instruction-count-based events
279 comInstEventQueue[0]->serviceEvents(numInst);
280
281 // decode the instruction
282 inst = gtoh(inst);
283
284 TheISA::PCState pcState = thread->pcState();
285
286 if (isRomMicroPC(pcState.microPC())) {
287 stayAtPC = false;
288 curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
289 curMacroStaticInst);
290 } else if (!curMacroStaticInst) {
291 //We're not in the middle of a macro instruction
292 StaticInstPtr instPtr = NULL;
293
294 //Predecode, ie bundle up an ExtMachInst
295 //This should go away once the constructor can be set up properly
296 predecoder.setTC(thread->getTC());
297 //If more fetch data is needed, pass it in.
298 Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
299 //if(predecoder.needMoreBytes())
300 predecoder.moreBytes(pcState, fetchPC, inst);
301 //else
302 // predecoder.process();
303
304 //If an instruction is ready, decode it. Otherwise, we'll have to
305 //fetch beyond the MachInst at the current pc.
306 if (predecoder.extMachInstReady()) {
307 stayAtPC = false;
308 ExtMachInst machInst = predecoder.getExtMachInst(pcState);
309 thread->pcState(pcState);
310 instPtr = StaticInst::decode(machInst, pcState.instAddr());
311 } else {
312 stayAtPC = true;
313 fetchOffset += sizeof(MachInst);
314 }
315
316 //If we decoded an instruction and it's microcoded, start pulling
317 //out micro ops
318 if (instPtr && instPtr->isMacroop()) {
319 curMacroStaticInst = instPtr;
320 curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
321 } else {
322 curStaticInst = instPtr;
323 }
324 } else {
325 //Read the next micro op from the macro op
326 curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
327 }
328
329 //If we decoded an instruction this "tick", record information about it.
330 if(curStaticInst)
331 {
332#if TRACING_ON
333 traceData = tracer->getInstRecord(curTick, tc,
333 traceData = tracer->getInstRecord(curTick(), tc,
334 curStaticInst, thread->pcState(), curMacroStaticInst);
335
336 DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
337 curStaticInst->getName(), curStaticInst->machInst);
338#endif // TRACING_ON
339 }
340}
341
342void
343BaseSimpleCPU::postExecute()
344{
345 assert(curStaticInst);
346
347 TheISA::PCState pc = tc->pcState();
348 Addr instAddr = pc.instAddr();
349#if FULL_SYSTEM
350 if (thread->profile) {
351 bool usermode = TheISA::inUserMode(tc);
352 thread->profilePC = usermode ? 1 : instAddr;
353 ProfileNode *node = thread->profile->consume(tc, curStaticInst);
354 if (node)
355 thread->profileNode = node;
356 }
357#endif
358
359 if (curStaticInst->isMemRef()) {
360 numMemRefs++;
361 }
362
363 if (curStaticInst->isLoad()) {
364 ++numLoad;
365 comLoadEventQueue[0]->serviceEvents(numLoad);
366 }
367
368 if (CPA::available()) {
369 CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr());
370 }
371
372 traceFunctions(instAddr);
373
374 if (traceData) {
375 traceData->dump();
376 delete traceData;
377 traceData = NULL;
378 }
379}
380
381
382void
383BaseSimpleCPU::advancePC(Fault fault)
384{
385 //Since we're moving to a new pc, zero out the offset
386 fetchOffset = 0;
387 if (fault != NoFault) {
388 curMacroStaticInst = StaticInst::nullStaticInstPtr;
389 fault->invoke(tc, curStaticInst);
390 predecoder.reset();
391 } else {
392 if (curStaticInst) {
393 if (curStaticInst->isLastMicroop())
394 curMacroStaticInst = StaticInst::nullStaticInstPtr;
395 TheISA::PCState pcState = thread->pcState();
396 TheISA::advancePC(pcState, curStaticInst);
397 thread->pcState(pcState);
398 }
399 }
400}
401
402/*Fault
403BaseSimpleCPU::CacheOp(uint8_t Op, Addr EffAddr)
404{
405 // translate to physical address
406 Fault fault = NoFault;
407 int CacheID = Op & 0x3; // Lower 3 bits identify Cache
408 int CacheOP = Op >> 2; // Upper 3 bits identify Cache Operation
409 if(CacheID > 1)
410 {
411 warn("CacheOps not implemented for secondary/tertiary caches\n");
412 }
413 else
414 {
415 switch(CacheOP)
416 { // Fill Packet Type
417 case 0: warn("Invalidate Cache Op\n");
418 break;
419 case 1: warn("Index Load Tag Cache Op\n");
420 break;
421 case 2: warn("Index Store Tag Cache Op\n");
422 break;
423 case 4: warn("Hit Invalidate Cache Op\n");
424 break;
425 case 5: warn("Fill/Hit Writeback Invalidate Cache Op\n");
426 break;
427 case 6: warn("Hit Writeback\n");
428 break;
429 case 7: warn("Fetch & Lock Cache Op\n");
430 break;
431 default: warn("Unimplemented Cache Op\n");
432 }
433 }
434 return fault;
435}*/
334 curStaticInst, thread->pcState(), curMacroStaticInst);
335
336 DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
337 curStaticInst->getName(), curStaticInst->machInst);
338#endif // TRACING_ON
339 }
340}
341
342void
343BaseSimpleCPU::postExecute()
344{
345 assert(curStaticInst);
346
347 TheISA::PCState pc = tc->pcState();
348 Addr instAddr = pc.instAddr();
349#if FULL_SYSTEM
350 if (thread->profile) {
351 bool usermode = TheISA::inUserMode(tc);
352 thread->profilePC = usermode ? 1 : instAddr;
353 ProfileNode *node = thread->profile->consume(tc, curStaticInst);
354 if (node)
355 thread->profileNode = node;
356 }
357#endif
358
359 if (curStaticInst->isMemRef()) {
360 numMemRefs++;
361 }
362
363 if (curStaticInst->isLoad()) {
364 ++numLoad;
365 comLoadEventQueue[0]->serviceEvents(numLoad);
366 }
367
368 if (CPA::available()) {
369 CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr());
370 }
371
372 traceFunctions(instAddr);
373
374 if (traceData) {
375 traceData->dump();
376 delete traceData;
377 traceData = NULL;
378 }
379}
380
381
382void
383BaseSimpleCPU::advancePC(Fault fault)
384{
385 //Since we're moving to a new pc, zero out the offset
386 fetchOffset = 0;
387 if (fault != NoFault) {
388 curMacroStaticInst = StaticInst::nullStaticInstPtr;
389 fault->invoke(tc, curStaticInst);
390 predecoder.reset();
391 } else {
392 if (curStaticInst) {
393 if (curStaticInst->isLastMicroop())
394 curMacroStaticInst = StaticInst::nullStaticInstPtr;
395 TheISA::PCState pcState = thread->pcState();
396 TheISA::advancePC(pcState, curStaticInst);
397 thread->pcState(pcState);
398 }
399 }
400}
401
402/*Fault
403BaseSimpleCPU::CacheOp(uint8_t Op, Addr EffAddr)
404{
405 // translate to physical address
406 Fault fault = NoFault;
407 int CacheID = Op & 0x3; // Lower 3 bits identify Cache
408 int CacheOP = Op >> 2; // Upper 3 bits identify Cache Operation
409 if(CacheID > 1)
410 {
411 warn("CacheOps not implemented for secondary/tertiary caches\n");
412 }
413 else
414 {
415 switch(CacheOP)
416 { // Fill Packet Type
417 case 0: warn("Invalidate Cache Op\n");
418 break;
419 case 1: warn("Index Load Tag Cache Op\n");
420 break;
421 case 2: warn("Index Store Tag Cache Op\n");
422 break;
423 case 4: warn("Hit Invalidate Cache Op\n");
424 break;
425 case 5: warn("Fill/Hit Writeback Invalidate Cache Op\n");
426 break;
427 case 6: warn("Hit Writeback\n");
428 break;
429 case 7: warn("Fetch & Lock Cache Op\n");
430 break;
431 default: warn("Unimplemented Cache Op\n");
432 }
433 }
434 return fault;
435}*/