Add in files from merge-bare-iron, get them compiling in FS and SE mode
[gem5.git] / src / cpu / base.hh
1 /*
2 * Copyright (c) 2002-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;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 * Nathan Binkert
30 */
31
32 #ifndef __CPU_BASE_HH__
33 #define __CPU_BASE_HH__
34
35 #include <vector>
36
37 #include "arch/isa_traits.hh"
38 #include "base/statistics.hh"
39 #include "config/full_system.hh"
40 #include "sim/eventq.hh"
41 #include "sim/insttracer.hh"
42 #include "mem/mem_object.hh"
43
44 #if FULL_SYSTEM
45 #include "arch/interrupts.hh"
46 #endif
47
48 class BranchPred;
49 class CheckerCPU;
50 class ThreadContext;
51 class System;
52 class Port;
53
54 namespace TheISA
55 {
56 class Predecoder;
57 }
58
59 class CPUProgressEvent : public Event
60 {
61 protected:
62 Tick interval;
63 Counter lastNumInst;
64 BaseCPU *cpu;
65
66 public:
67 CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu);
68
69 void process();
70
71 virtual const char *description();
72 };
73
74 class BaseCPU : public MemObject
75 {
76 protected:
77 // CPU's clock period in terms of the number of ticks of curTime.
78 Tick clock;
79 // @todo remove me after debugging with legion done
80 Tick instCnt;
81
82 public:
83 // Tick currentTick;
84 inline Tick frequency() const { return Clock::Frequency / clock; }
85 inline Tick ticks(int numCycles) const { return clock * numCycles; }
86 inline Tick curCycle() const { return curTick / clock; }
87 inline Tick tickToCycles(Tick val) const { return val / clock; }
88 // @todo remove me after debugging with legion done
89 Tick instCount() { return instCnt; }
90
91 /** The next cycle the CPU should be scheduled, given a cache
92 * access or quiesce event returning on this cycle. This function
93 * may return curTick if the CPU should run on the current cycle.
94 */
95 Tick nextCycle();
96
97 /** The next cycle the CPU should be scheduled, given a cache
98 * access or quiesce event returning on the given Tick. This
99 * function may return curTick if the CPU should run on the
100 * current cycle.
101 * @param begin_tick The tick that the event is completing on.
102 */
103 Tick nextCycle(Tick begin_tick);
104
105 #if FULL_SYSTEM
106 protected:
107 // uint64_t interrupts[TheISA::NumInterruptLevels];
108 // uint64_t intstatus;
109 TheISA::Interrupts interrupts;
110
111 public:
112 virtual void post_interrupt(int int_num, int index);
113 virtual void clear_interrupt(int int_num, int index);
114 virtual void clear_interrupts();
115 virtual uint64_t get_interrupts(int int_num);
116
117 bool check_interrupts(ThreadContext * tc) const
118 { return interrupts.check_interrupts(tc); }
119
120 class ProfileEvent : public Event
121 {
122 private:
123 BaseCPU *cpu;
124 int interval;
125
126 public:
127 ProfileEvent(BaseCPU *cpu, int interval);
128 void process();
129 };
130 ProfileEvent *profileEvent;
131 #endif
132
133 protected:
134 std::vector<ThreadContext *> threadContexts;
135 std::vector<TheISA::Predecoder *> predecoders;
136
137 Trace::InstTracer * tracer;
138
139 public:
140
141 /// Provide access to the tracer pointer
142 Trace::InstTracer * getTracer() { return tracer; }
143
144 /// Notify the CPU that the indicated context is now active. The
145 /// delay parameter indicates the number of ticks to wait before
146 /// executing (typically 0 or 1).
147 virtual void activateContext(int thread_num, int delay) {}
148
149 /// Notify the CPU that the indicated context is now suspended.
150 virtual void suspendContext(int thread_num) {}
151
152 /// Notify the CPU that the indicated context is now deallocated.
153 virtual void deallocateContext(int thread_num) {}
154
155 /// Notify the CPU that the indicated context is now halted.
156 virtual void haltContext(int thread_num) {}
157
158 /// Given a Thread Context pointer return the thread num
159 int findContext(ThreadContext *tc);
160
161 /// Given a thread num get tho thread context for it
162 ThreadContext *getContext(int tn) { return threadContexts[tn]; }
163
164 public:
165 struct Params
166 {
167 std::string name;
168 int numberOfThreads;
169 bool deferRegistration;
170 Counter max_insts_any_thread;
171 Counter max_insts_all_threads;
172 Counter max_loads_any_thread;
173 Counter max_loads_all_threads;
174 Tick clock;
175 bool functionTrace;
176 Tick functionTraceStart;
177 System *system;
178 int cpu_id;
179 Trace::InstTracer * tracer;
180
181 Tick phase;
182 #if FULL_SYSTEM
183 Tick profile;
184
185 bool do_statistics_insts;
186 bool do_checkpoint_insts;
187 bool do_quiesce;
188 #endif
189 Tick progress_interval;
190 BaseCPU *checker;
191
192 #if THE_ISA == MIPS_ISA
193 /* Note: It looks like it will be better to allow simulator users
194 to specify the values of individual variables instead of requiring
195 users to define the values of entire registers
196 Especially since a lot of these variables can be created from other
197 user parameters (cache descriptions)
198 -jpp
199 */
200 // MIPS CP0 State - First individual variables
201 // Page numbers refer to revision 2.50 (July 2005) of the MIPS32 ARM, Volume III (PRA)
202 unsigned CP0_IntCtl_IPTI; // Page 93, IP Timer Interrupt
203 unsigned CP0_IntCtl_IPPCI; // Page 94, IP Performance Counter Interrupt
204 unsigned CP0_SrsCtl_HSS; // Page 95, Highest Implemented Shadow Set
205 unsigned CP0_PRId_CompanyOptions; // Page 105, Manufacture options
206 unsigned CP0_PRId_CompanyID; // Page 105, Company ID - (0-255, 1=>MIPS)
207 unsigned CP0_PRId_ProcessorID; // Page 105
208 unsigned CP0_PRId_Revision; // Page 105
209 unsigned CP0_EBase_CPUNum; // Page 106, CPU Number in a multiprocessor system
210 unsigned CP0_Config_BE; // Page 108, Big/Little Endian mode
211 unsigned CP0_Config_AT; //Page 109
212 unsigned CP0_Config_AR; //Page 109
213 unsigned CP0_Config_MT; //Page 109
214 unsigned CP0_Config_VI; //Page 109
215 unsigned CP0_Config1_M; // Page 110
216 unsigned CP0_Config1_MMU; // Page 110
217 unsigned CP0_Config1_IS; // Page 110
218 unsigned CP0_Config1_IL; // Page 111
219 unsigned CP0_Config1_IA; // Page 111
220 unsigned CP0_Config1_DS; // Page 111
221 unsigned CP0_Config1_DL; // Page 112
222 unsigned CP0_Config1_DA; // Page 112
223 bool CP0_Config1_C2; // Page 112
224 bool CP0_Config1_MD;// Page 112 - Technically not used in MIPS32
225 bool CP0_Config1_PC;// Page 112
226 bool CP0_Config1_WR;// Page 113
227 bool CP0_Config1_CA;// Page 113
228 bool CP0_Config1_EP;// Page 113
229 bool CP0_Config1_FP;// Page 113
230 bool CP0_Config2_M; // Page 114
231 unsigned CP0_Config2_TU;// Page 114
232 unsigned CP0_Config2_TS;// Page 114
233 unsigned CP0_Config2_TL;// Page 115
234 unsigned CP0_Config2_TA;// Page 115
235 unsigned CP0_Config2_SU;// Page 115
236 unsigned CP0_Config2_SS;// Page 115
237 unsigned CP0_Config2_SL;// Page 116
238 unsigned CP0_Config2_SA;// Page 116
239 bool CP0_Config3_M; //// Page 117
240 bool CP0_Config3_DSPP;// Page 117
241 bool CP0_Config3_LPA;// Page 117
242 bool CP0_Config3_VEIC;// Page 118
243 bool CP0_Config3_VInt; // Page 118
244 bool CP0_Config3_SP;// Page 118
245 bool CP0_Config3_MT;// Page 119
246 bool CP0_Config3_SM;// Page 119
247 bool CP0_Config3_TL;// Page 119
248
249 bool CP0_WatchHi_M; // Page 124
250 bool CP0_PerfCtr_M; // Page 130
251 bool CP0_PerfCtr_W; // Page 130
252
253
254 // Then, whole registers
255 unsigned CP0_PRId;
256 unsigned CP0_Config;
257 unsigned CP0_Config1;
258 unsigned CP0_Config2;
259 unsigned CP0_Config3;
260
261 #endif
262
263 Params();
264 };
265
266 const Params *params;
267
268 BaseCPU(Params *params);
269 virtual ~BaseCPU();
270
271 virtual void init();
272 virtual void startup();
273 virtual void regStats();
274
275 virtual void activateWhenReady(int tid) {};
276
277 void registerThreadContexts();
278
279 /// Prepare for another CPU to take over execution. When it is
280 /// is ready (drained pipe) it signals the sampler.
281 virtual void switchOut();
282
283 /// Take over execution from the given CPU. Used for warm-up and
284 /// sampling.
285 virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
286
287 /**
288 * Number of threads we're actually simulating (<= SMT_MAX_THREADS).
289 * This is a constant for the duration of the simulation.
290 */
291 int number_of_threads;
292
293 /**
294 * Vector of per-thread instruction-based event queues. Used for
295 * scheduling events based on number of instructions committed by
296 * a particular thread.
297 */
298 EventQueue **comInstEventQueue;
299
300 /**
301 * Vector of per-thread load-based event queues. Used for
302 * scheduling events based on number of loads committed by
303 *a particular thread.
304 */
305 EventQueue **comLoadEventQueue;
306
307 System *system;
308
309 Tick phase;
310
311 #if FULL_SYSTEM
312 /**
313 * Serialize this object to the given output stream.
314 * @param os The stream to serialize to.
315 */
316 virtual void serialize(std::ostream &os);
317
318 /**
319 * Reconstruct the state of this object from a checkpoint.
320 * @param cp The checkpoint use.
321 * @param section The section name of this object
322 */
323 virtual void unserialize(Checkpoint *cp, const std::string &section);
324
325 #endif
326
327 /**
328 * Return pointer to CPU's branch predictor (NULL if none).
329 * @return Branch predictor pointer.
330 */
331 virtual BranchPred *getBranchPred() { return NULL; };
332
333 virtual Counter totalInstructions() const { return 0; }
334
335 // Function tracing
336 private:
337 bool functionTracingEnabled;
338 std::ostream *functionTraceStream;
339 Addr currentFunctionStart;
340 Addr currentFunctionEnd;
341 Tick functionEntryTick;
342 void enableFunctionTrace();
343 void traceFunctionsInternal(Addr pc);
344
345 protected:
346 void traceFunctions(Addr pc)
347 {
348 if (functionTracingEnabled)
349 traceFunctionsInternal(pc);
350 }
351
352 private:
353 static std::vector<BaseCPU *> cpuList; //!< Static global cpu list
354
355 public:
356 static int numSimulatedCPUs() { return cpuList.size(); }
357 static Counter numSimulatedInstructions()
358 {
359 Counter total = 0;
360
361 int size = cpuList.size();
362 for (int i = 0; i < size; ++i)
363 total += cpuList[i]->totalInstructions();
364
365 return total;
366 }
367
368 public:
369 // Number of CPU cycles simulated
370 Stats::Scalar<> numCycles;
371 };
372
373 #endif // __CPU_BASE_HH__