2 * Copyright (c) 2006 The Regents of The University of Michigan
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.
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.
32 #include "config/use_checker.hh"
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"
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"
49 MipsO3CPU<Impl>::MipsO3CPU(Params *params)
50 : FullO3CPU<Impl>(params)
52 DPRINTF(O3CPU, "Creating MipsO3CPU object.\n");
54 // Setup any thread state.
55 this->thread.resize(this->numThreads);
57 for (int i = 0; i < this->numThreads; ++i) {
58 if (i < params->workload.size()) {
59 DPRINTF(O3CPU, "Workload[%i] process is %#x",
61 this->thread[i] = new Thread(this, i, params->workload[i], i);
63 this->thread[i]->setStatus(ThreadContext::Suspended);
68 //Allocate Empty thread so M5 can use later
69 //when scheduling threads to CPU
70 Process* dummy_proc = NULL;
72 this->thread[i] = new Thread(this, i, dummy_proc, i);
73 //usedTids[i] = false;
78 // Setup the TC that will serve as the interface to the threads/CPU.
79 MipsTC<Impl> *mips_tc =
84 // If we're using a checker, then the TC should be the
85 // CheckerThreadContext.
87 if (params->checker) {
88 tc = new CheckerThreadContext<MipsTC<Impl> >(
89 mips_tc, this->checker);
94 mips_tc->thread = this->thread[i];
96 // Give the thread the TC.
97 this->thread[i]->tc = tc;
99 // Add the TC to the CPU's list of TC's.
100 this->threadContexts.push_back(tc);
103 for (int i=0; i < this->numThreads; i++) {
104 this->thread[i]->setFuncExeInst(0);
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);
115 this->rob.setCPU(this);
116 this->regFile.setCPU(this);
122 template <class Impl>
124 MipsO3CPU<Impl>::regStats()
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();
136 template <class Impl>
138 MipsO3CPU<Impl>::readMiscReg(int misc_reg, unsigned tid)
140 return this->regFile.readMiscReg(misc_reg, tid);
143 template <class Impl>
145 MipsO3CPU<Impl>::readMiscRegWithEffect(int misc_reg, unsigned tid)
147 return this->regFile.readMiscRegWithEffect(misc_reg, tid);
150 template <class Impl>
152 MipsO3CPU<Impl>::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid)
154 this->regFile.setMiscReg(misc_reg, val, tid);
157 template <class Impl>
159 MipsO3CPU<Impl>::setMiscRegWithEffect(int misc_reg, const MiscReg &val,
162 this->regFile.setMiscRegWithEffect(misc_reg, val, tid);
165 template <class Impl>
167 MipsO3CPU<Impl>::squashFromTC(unsigned tid)
169 this->thread[tid]->inSyscall = true;
170 this->commit.generateTCEvent(tid);
173 template <class Impl>
175 MipsO3CPU<Impl>::trap(Fault fault, unsigned tid)
177 // Pass the thread's TC into the invoke method.
178 fault->invoke(this->threadContexts[tid]);
183 template <class Impl>
185 MipsO3CPU<Impl>::syscall(int64_t callnum, int tid)
187 DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
189 DPRINTF(Activity,"Activity: syscall() called.\n");
191 // Temporarily increase this by one to account for the syscall
193 ++(this->thread[tid]->funcExeInst);
195 // Execute the actual syscall.
196 this->thread[tid]->syscall(callnum);
198 // Decrease funcExeInst by one as the normal commit will handle
200 --(this->thread[tid]->funcExeInst);
202 DPRINTF(O3CPU, "[tid:%i] Register 2 is %i ", tid, this->readIntReg(2));
205 template <class Impl>
207 MipsO3CPU<Impl>::getSyscallArg(int i, int tid)
209 return this->readArchIntReg(MipsISA::ArgumentReg0 + i, tid);
212 template <class Impl>
214 MipsO3CPU<Impl>::setSyscallArg(int i, IntReg val, int tid)
216 this->setArchIntReg(MipsISA::ArgumentReg0 + i, val, tid);
219 template <class Impl>
221 MipsO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
223 // check for error condition.
224 if (return_value.successful()) {
226 this->setArchIntReg(TheISA::SyscallSuccessReg, 0, tid);
227 this->setArchIntReg(TheISA::ReturnValueReg, return_value.value(), tid);
229 // got an error, return details
230 this->setArchIntReg(TheISA::SyscallSuccessReg,
231 (TheISA::IntReg) -1, tid);
232 this->setArchIntReg(TheISA::ReturnValueReg, -return_value.value(), tid);