*MiscReg->*MiscRegNoEffect, *MiscRegWithEffect->*MiscReg
[gem5.git] / src / cpu / o3 / mips / cpu_impl.hh
1 /*
2 * Copyright (c) 2006 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: Kevin Lim
29 * Korey Sewell
30 */
31
32 #include "config/use_checker.hh"
33
34 #include "arch/mips/faults.hh"
35 #include "base/cprintf.hh"
36 #include "base/statistics.hh"
37 #include "base/timebuf.hh"
38 #include "cpu/checker/thread_context.hh"
39 #include "sim/sim_events.hh"
40 #include "sim/stats.hh"
41
42 #include "cpu/o3/mips/cpu.hh"
43 #include "cpu/o3/mips/params.hh"
44 #include "cpu/o3/mips/thread_context.hh"
45 #include "cpu/o3/comm.hh"
46 #include "cpu/o3/thread_state.hh"
47
48 template <class Impl>
49 MipsO3CPU<Impl>::MipsO3CPU(Params *params)
50 : FullO3CPU<Impl>(params)
51 {
52 DPRINTF(O3CPU, "Creating MipsO3CPU object.\n");
53
54 // Setup any thread state.
55 this->thread.resize(this->numThreads);
56
57 for (int i = 0; i < this->numThreads; ++i) {
58 if (i < params->workload.size()) {
59 DPRINTF(O3CPU, "Workload[%i] process is %#x",
60 i, this->thread[i]);
61 this->thread[i] = new Thread(this, i, params->workload[i], i);
62
63 this->thread[i]->setStatus(ThreadContext::Suspended);
64
65 //usedTids[i] = true;
66 //threadMap[i] = i;
67 } else {
68 //Allocate Empty thread so M5 can use later
69 //when scheduling threads to CPU
70 Process* dummy_proc = NULL;
71
72 this->thread[i] = new Thread(this, i, dummy_proc, i);
73 //usedTids[i] = false;
74 }
75
76 ThreadContext *tc;
77
78 // Setup the TC that will serve as the interface to the threads/CPU.
79 MipsTC<Impl> *mips_tc =
80 new MipsTC<Impl>;
81
82 tc = mips_tc;
83
84 // If we're using a checker, then the TC should be the
85 // CheckerThreadContext.
86 #if USE_CHECKER
87 if (params->checker) {
88 tc = new CheckerThreadContext<MipsTC<Impl> >(
89 mips_tc, this->checker);
90 }
91 #endif
92
93 mips_tc->cpu = this;
94 mips_tc->thread = this->thread[i];
95
96 // Give the thread the TC.
97 this->thread[i]->tc = tc;
98
99 // Add the TC to the CPU's list of TC's.
100 this->threadContexts.push_back(tc);
101 }
102
103 for (int i=0; i < this->numThreads; i++) {
104 this->thread[i]->setFuncExeInst(0);
105 }
106
107 // Sets CPU pointers. These must be set at this level because the CPU
108 // pointers are defined to be the highest level of CPU class.
109 this->fetch.setCPU(this);
110 this->decode.setCPU(this);
111 this->rename.setCPU(this);
112 this->iew.setCPU(this);
113 this->commit.setCPU(this);
114
115 this->rob.setCPU(this);
116 this->regFile.setCPU(this);
117
118 lockAddr = 0;
119 lockFlag = false;
120 }
121
122 template <class Impl>
123 void
124 MipsO3CPU<Impl>::regStats()
125 {
126 // Register stats for everything that has stats.
127 this->fullCPURegStats();
128 this->fetch.regStats();
129 this->decode.regStats();
130 this->rename.regStats();
131 this->iew.regStats();
132 this->commit.regStats();
133 }
134
135
136 template <class Impl>
137 MiscReg
138 MipsO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, unsigned tid)
139 {
140 return this->regFile.readMiscRegNoEffect(misc_reg, tid);
141 }
142
143 template <class Impl>
144 MiscReg
145 MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
146 {
147 return this->regFile.readMiscReg(misc_reg, tid);
148 }
149
150 template <class Impl>
151 void
152 MipsO3CPU<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
153 {
154 this->regFile.setMiscRegNoEffect(misc_reg, val, tid);
155 }
156
157 template <class Impl>
158 void
159 MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val,
160 unsigned tid)
161 {
162 this->regFile.setMiscReg(misc_reg, val, tid);
163 }
164
165 template <class Impl>
166 void
167 MipsO3CPU<Impl>::squashFromTC(unsigned tid)
168 {
169 this->thread[tid]->inSyscall = true;
170 this->commit.generateTCEvent(tid);
171 }
172
173 template <class Impl>
174 void
175 MipsO3CPU<Impl>::trap(Fault fault, unsigned tid)
176 {
177 // Pass the thread's TC into the invoke method.
178 fault->invoke(this->threadContexts[tid]);
179 }
180
181 #if !FULL_SYSTEM
182
183 template <class Impl>
184 void
185 MipsO3CPU<Impl>::syscall(int64_t callnum, int tid)
186 {
187 DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
188
189 DPRINTF(Activity,"Activity: syscall() called.\n");
190
191 // Temporarily increase this by one to account for the syscall
192 // instruction.
193 ++(this->thread[tid]->funcExeInst);
194
195 // Execute the actual syscall.
196 this->thread[tid]->syscall(callnum);
197
198 // Decrease funcExeInst by one as the normal commit will handle
199 // incrementing it.
200 --(this->thread[tid]->funcExeInst);
201
202 DPRINTF(O3CPU, "[tid:%i] Register 2 is %i ", tid, this->readIntReg(2));
203 }
204
205 template <class Impl>
206 TheISA::IntReg
207 MipsO3CPU<Impl>::getSyscallArg(int i, int tid)
208 {
209 return this->readArchIntReg(MipsISA::ArgumentReg0 + i, tid);
210 }
211
212 template <class Impl>
213 void
214 MipsO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
215 {
216 this->setArchIntReg(MipsISA::ArgumentReg0 + i, val, tid);
217 }
218
219 template <class Impl>
220 void
221 MipsO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
222 {
223 TheISA::setSyscallReturn(return_value, this->tcBase(tid));
224 }
225 #endif