gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mt.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 MIPS Technologies, Inc.
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: Korey Sewell
29  */
30 
31 #ifndef __ARCH_MIPS_MT_HH__
32 #define __ARCH_MIPS_MT_HH__
33 
40 #include <iostream>
41 
42 #include "arch/mips/faults.hh"
43 #include "arch/mips/isa_traits.hh"
46 #include "arch/mips/registers.hh"
47 #include "base/bitfield.hh"
48 #include "base/misc.hh"
49 #include "base/trace.hh"
50 
51 namespace MipsISA
52 {
53 
54 template <class TC>
55 inline unsigned
57 {
58  TCBindReg tcbind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
59  return tcbind.curVPE;
60 }
61 
62 template <class TC>
63 inline unsigned
65 {
66  VPEControlReg vpeCtrl = tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL);
67  return vpeCtrl.targTC;
68 }
69 
70 template <class TC>
71 inline void
72 haltThread(TC *tc)
73 {
74  if (tc->status() == TC::Active) {
75  tc->halt();
76 
77  // Save last known PC in TCRestart
78  // @TODO: Needs to check if this is a branch and if so,
79  // take previous instruction
80  PCState pc = tc->pcState();
81  tc->setMiscReg(MISCREG_TC_RESTART, pc.npc());
82 
83  warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x",
84  curTick(), tc->threadId(), tc->getCpuPtr()->name(),
85  pc.pc(), pc.npc());
86  }
87 }
88 
89 template <class TC>
90 inline void
92 {
93  if (tc->status() != TC::Active) {
94  // Restore PC from TCRestart
95  Addr restartPC = tc->readMiscRegNoEffect(MISCREG_TC_RESTART);
96 
97  // TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY
98  tc->pcState(restartPC);
99  tc->activate();
100 
101  warn("%i: Restoring thread %i in %s @ PC %x",
102  curTick(), tc->threadId(), tc->getCpuPtr()->name(), restartPC);
103  }
104 }
105 
106 template <class TC>
107 void
108 forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
109 {
110  MVPConf0Reg mvpConf = tc->readMiscRegNoEffect(MISCREG_MVP_CONF0);
111  int num_threads = mvpConf.ptc + 1;
112 
113  int success = 0;
114  for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
115  TCBindReg tidTCBind =
116  tc->readRegOtherThread(MISCREG_TC_BIND + Misc_Reg_Base, tid);
117  TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
118 
119  if (tidTCBind.curVPE == tcBind.curVPE) {
120 
121  TCStatusReg tidTCStatus =
122  tc->readRegOtherThread(MISCREG_TC_STATUS +
123  Misc_Reg_Base,tid);
124 
125  TCHaltReg tidTCHalt =
126  tc->readRegOtherThread(MISCREG_TC_HALT + Misc_Reg_Base,tid);
127 
128  if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
129  tidTCStatus.a == 0 && success == 0) {
130 
131  tc->setRegOtherThread(MISCREG_TC_RESTART +
132  Misc_Reg_Base, Rs, tid);
133  tc->setRegOtherThread(Rd_bits, Rt, tid);
134 
135  StatusReg status = tc->readMiscReg(MISCREG_STATUS);
136  TCStatusReg tcStatus = tc->readMiscReg(MISCREG_TC_STATUS);
137 
138  // Set Run-State to Running
139  tidTCStatus.rnst = 0;
140  // Set Delay-Slot to 0
141  tidTCStatus.tds = 0;
142  // Set Dirty TC to 1
143  tidTCStatus.dt = 1;
144  // Set Activated to 1
145  tidTCStatus.a = 1;
146  // Set status to previous thread's status
147  tidTCStatus.tksu = status.ksu;
148  // Set ASID to previous thread's state
149  tidTCStatus.asid = tcStatus.asid;
150 
151  // Write Status Register
152  tc->setRegOtherThread(MISCREG_TC_STATUS + Misc_Reg_Base,
153  tidTCStatus, tid);
154 
155  // Mark As Successful Fork
156  success = 1;
157  }
158  } else {
159  std::cerr << "Bad VPEs" << std::endl;
160  }
161  }
162 
163  if (success == 0) {
164  VPEControlReg vpeControl =
165  tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL);
166  vpeControl.excpt = 1;
167  tc->setMiscReg(MISCREG_VPE_CONTROL, vpeControl);
168  fault = std::make_shared<ThreadFault>();
169  }
170 }
171 
172 
173 template <class TC>
174 int
175 yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
176 {
177  if (src_reg == 0) {
178  MVPConf0Reg mvpConf0 = tc->readMiscRegNoEffect(MISCREG_MVP_CONF0);
179  ThreadID num_threads = mvpConf0.ptc + 1;
180 
181  int ok = 0;
182 
183  // Get Current VPE & TC numbers from calling thread
184  TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
185 
186  for (ThreadID tid = 0; tid < num_threads; tid++) {
187  TCStatusReg tidTCStatus =
188  tc->readRegOtherThread(MISCREG_TC_STATUS + Misc_Reg_Base,
189  tid);
190  TCHaltReg tidTCHalt =
191  tc->readRegOtherThread(MISCREG_TC_HALT + Misc_Reg_Base,
192  tid);
193  TCBindReg tidTCBind =
194  tc->readRegOtherThread(MISCREG_TC_BIND + Misc_Reg_Base,
195  tid);
196 
197  if (tidTCBind.curVPE == tcBind.curVPE &&
198  tidTCBind.curTC == tcBind.curTC &&
199  tidTCStatus.da == 1 &&
200  tidTCHalt.h == 0 &&
201  tidTCStatus.a == 1) {
202  ok = 1;
203  }
204  }
205 
206  if (ok == 1) {
207  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
208  tcStatus.a = 0;
209  tc->setMiscReg(MISCREG_TC_STATUS, tcStatus);
210  warn("%i: Deactivating Hardware Thread Context #%i",
211  curTick(), tc->threadId());
212  }
213  } else if (src_reg > 0) {
214  if (src_reg && !yield_mask != 0) {
215  VPEControlReg vpeControl = tc->readMiscReg(MISCREG_VPE_CONTROL);
216  vpeControl.excpt = 2;
217  tc->setMiscReg(MISCREG_VPE_CONTROL, vpeControl);
218  fault = std::make_shared<ThreadFault>();
219  } else {
220  }
221  } else if (src_reg != -2) {
222  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
223  VPEControlReg vpeControl =
224  tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL);
225 
226  if (vpeControl.ysi == 1 && tcStatus.dt == 1 ) {
227  vpeControl.excpt = 4;
228  fault = std::make_shared<ThreadFault>();
229  } else {
230  }
231  }
232 
233  return src_reg & yield_mask;
234 }
235 
236 
237 // TC will usually be a object derived from ThreadContext
238 // (src/cpu/thread_context.hh)
239 template <class TC>
240 inline void
242 {
243  // TCStatus' register view must be the same as
244  // Status register view for CU, MX, KSU bits
245  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
246  StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS);
247 
248  status.cu = tcStatus.tcu;
249  status.mx = tcStatus.tmx;
250  status.ksu = tcStatus.tksu;
251 
252  tc->setMiscRegNoEffect(MISCREG_STATUS, status);
253 }
254 
255 // TC will usually be a object derived from ThreadContext
256 // (src/cpu/thread_context.hh)
257 template <class TC>
258 inline void
260 {
261  // TCStatus' register view must be the same as
262  // Status register view for CU, MX, KSU bits
263  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
264  StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS);
265 
266  tcStatus.tcu = status.cu;
267  tcStatus.tmx = status.mx;
268  tcStatus.tksu = status.ksu;
269 
270  tc->setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus);
271 }
272 
273 } // namespace MipsISA
274 
275 
276 #endif
void updateStatusView(TC *tc)
Definition: mt.hh:241
void restoreThread(TC *tc)
Definition: mt.hh:91
void updateTCStatusView(TC *tc)
Definition: mt.hh:259
Addr pc() const
Definition: types.hh:138
#define warn(...)
Definition: misc.hh:219
Bitfield< 5, 0 > status
Definition: miscregs.hh:1604
Tick curTick()
The current simulated tick.
Definition: core.hh:47
Bitfield< 4 > pc
unsigned getVirtProcNum(TC *tc)
Definition: mt.hh:56
unsigned getTargetThread(TC *tc)
Definition: mt.hh:64
void haltThread(TC *tc)
Definition: mt.hh:72
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
int yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
Definition: mt.hh:175
void forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
Definition: mt.hh:108
const int Misc_Reg_Base
Definition: registers.hh:281
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:171
Addr npc() const
Definition: types.hh:141
std::shared_ptr< FaultBase > Fault
Definition: types.hh:184

Generated on Fri Jun 9 2017 13:03:36 for gem5 by doxygen 1.8.6