gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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/logging.hh"
49 #include "base/trace.hh"
50 #include "cpu/exec_context.hh"
51 
52 namespace MipsISA
53 {
54 
55 static inline RegVal
58 {
59  ThreadContext *otc = nullptr;
60  if (tid != InvalidThreadID)
61  otc = tc->getCpuPtr()->getContext(tid);
62  else
63  otc = tc;
64 
65  switch (reg.classValue()) {
66  case IntRegClass:
67  return otc->readIntReg(reg.index());
68  break;
69  case FloatRegClass:
70  return otc->readFloatReg(reg.index());
71  break;
72  case MiscRegClass:
73  return otc->readMiscReg(reg.index());
74  default:
75  panic("Unexpected reg class! (%s)", reg.className());
76  }
77 }
78 
79 static inline void
82 {
83  ThreadContext *otc = nullptr;
84  if (tid != InvalidThreadID)
85  otc = tc->getCpuPtr()->getContext(tid);
86  else
87  otc = tc;
88 
89  switch (reg.classValue()) {
90  case IntRegClass:
91  return otc->setIntReg(reg.index(), val);
92  break;
93  case FloatRegClass:
94  return otc->setFloatReg(reg.index(), val);
95  break;
96  case MiscRegClass:
97  return otc->setMiscReg(reg.index(), val);
98  default:
99  panic("Unexpected reg class! (%s)", reg.className());
100  }
101 }
102 
103 static inline RegVal
106 {
107  return readRegOtherThread(xc->tcBase(), reg, tid);
108 }
109 
110 static inline void
113 {
114  setRegOtherThread(xc->tcBase(), reg, val, tid);
115 }
116 
117 template <class TC>
118 inline unsigned
120 {
121  TCBindReg tcbind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
122  return tcbind.curVPE;
123 }
124 
125 template <class TC>
126 inline unsigned
128 {
129  VPEControlReg vpeCtrl = tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL);
130  return vpeCtrl.targTC;
131 }
132 
133 template <class TC>
134 inline void
135 haltThread(TC *tc)
136 {
137  if (tc->status() == TC::Active) {
138  tc->halt();
139 
140  // Save last known PC in TCRestart
141  // @TODO: Needs to check if this is a branch and if so,
142  // take previous instruction
143  PCState pc = tc->pcState();
144  tc->setMiscReg(MISCREG_TC_RESTART, pc.npc());
145 
146  warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x",
147  curTick(), tc->threadId(), tc->getCpuPtr()->name(),
148  pc.pc(), pc.npc());
149  }
150 }
151 
152 template <class TC>
153 inline void
155 {
156  if (tc->status() != TC::Active) {
157  // Restore PC from TCRestart
158  Addr restartPC = tc->readMiscRegNoEffect(MISCREG_TC_RESTART);
159 
160  // TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY
161  tc->pcState(restartPC);
162  tc->activate();
163 
164  warn("%i: Restoring thread %i in %s @ PC %x",
165  curTick(), tc->threadId(), tc->getCpuPtr()->name(), restartPC);
166  }
167 }
168 
169 template <class TC>
170 void
171 forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
172 {
173  MVPConf0Reg mvpConf = tc->readMiscRegNoEffect(MISCREG_MVP_CONF0);
174  int num_threads = mvpConf.ptc + 1;
175 
176  int success = 0;
177  for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) {
178  TCBindReg tidTCBind =
180  TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
181 
182  if (tidTCBind.curVPE == tcBind.curVPE) {
183 
184  TCStatusReg tidTCStatus =
186  tid);
187 
188  TCHaltReg tidTCHalt =
190  tid);
191 
192  if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
193  tidTCStatus.a == 0 && success == 0) {
194 
196  Rs, tid);
197  setRegOtherThread(tc, RegId(IntRegClass, Rd_bits), Rt, tid);
198 
199  StatusReg status = tc->readMiscReg(MISCREG_STATUS);
200  TCStatusReg tcStatus = tc->readMiscReg(MISCREG_TC_STATUS);
201 
202  // Set Run-State to Running
203  tidTCStatus.rnst = 0;
204  // Set Delay-Slot to 0
205  tidTCStatus.tds = 0;
206  // Set Dirty TC to 1
207  tidTCStatus.dt = 1;
208  // Set Activated to 1
209  tidTCStatus.a = 1;
210  // Set status to previous thread's status
211  tidTCStatus.tksu = status.ksu;
212  // Set ASID to previous thread's state
213  tidTCStatus.asid = tcStatus.asid;
214 
215  // Write Status Register
217  tidTCStatus, tid);
218 
219  // Mark As Successful Fork
220  success = 1;
221  }
222  } else {
223  std::cerr << "Bad VPEs" << std::endl;
224  }
225  }
226 
227  if (success == 0) {
228  VPEControlReg vpeControl =
229  tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL);
230  vpeControl.excpt = 1;
231  tc->setMiscReg(MISCREG_VPE_CONTROL, vpeControl);
232  fault = std::make_shared<ThreadFault>();
233  }
234 }
235 
236 
237 template <class TC>
238 int
239 yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
240 {
241  if (src_reg == 0) {
242  MVPConf0Reg mvpConf0 = tc->readMiscRegNoEffect(MISCREG_MVP_CONF0);
243  ThreadID num_threads = mvpConf0.ptc + 1;
244 
245  int ok = 0;
246 
247  // Get Current VPE & TC numbers from calling thread
248  TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND);
249 
250  for (ThreadID tid = 0; tid < num_threads; tid++) {
251  TCStatusReg tidTCStatus =
253  tid);
254  TCHaltReg tidTCHalt =
256  tid);
257  TCBindReg tidTCBind =
259  tid);
260 
261  if (tidTCBind.curVPE == tcBind.curVPE &&
262  tidTCBind.curTC == tcBind.curTC &&
263  tidTCStatus.da == 1 &&
264  tidTCHalt.h == 0 &&
265  tidTCStatus.a == 1) {
266  ok = 1;
267  }
268  }
269 
270  if (ok == 1) {
271  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
272  tcStatus.a = 0;
273  tc->setMiscReg(MISCREG_TC_STATUS, tcStatus);
274  warn("%i: Deactivating Hardware Thread Context #%i",
275  curTick(), tc->threadId());
276  }
277  } else if (src_reg > 0) {
278  if (src_reg && !yield_mask != 0) {
279  VPEControlReg vpeControl = tc->readMiscReg(MISCREG_VPE_CONTROL);
280  vpeControl.excpt = 2;
281  tc->setMiscReg(MISCREG_VPE_CONTROL, vpeControl);
282  fault = std::make_shared<ThreadFault>();
283  } else {
284  }
285  } else if (src_reg != -2) {
286  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
287  VPEControlReg vpeControl =
288  tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL);
289 
290  if (vpeControl.ysi == 1 && tcStatus.dt == 1 ) {
291  vpeControl.excpt = 4;
292  fault = std::make_shared<ThreadFault>();
293  } else {
294  }
295  }
296 
297  return src_reg & yield_mask;
298 }
299 
300 
301 // TC will usually be a object derived from ThreadContext
302 // (src/cpu/thread_context.hh)
303 template <class TC>
304 inline void
306 {
307  // TCStatus' register view must be the same as
308  // Status register view for CU, MX, KSU bits
309  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
310  StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS);
311 
312  status.cu = tcStatus.tcu;
313  status.mx = tcStatus.tmx;
314  status.ksu = tcStatus.tksu;
315 
316  tc->setMiscRegNoEffect(MISCREG_STATUS, status);
317 }
318 
319 // TC will usually be a object derived from ThreadContext
320 // (src/cpu/thread_context.hh)
321 template <class TC>
322 inline void
324 {
325  // TCStatus' register view must be the same as
326  // Status register view for CU, MX, KSU bits
327  TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS);
328  StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS);
329 
330  tcStatus.tcu = status.cu;
331  tcStatus.tmx = status.mx;
332  tcStatus.tksu = status.ksu;
333 
334  tc->setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus);
335 }
336 
337 } // namespace MipsISA
338 
339 
340 #endif
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
Bitfield< 5, 3 > reg
Definition: types.hh:89
Floating-point register.
Definition: reg_class.hh:58
virtual RegVal readIntReg(RegIndex reg_idx) const =0
Control (misc) register.
Definition: reg_class.hh:65
void updateStatusView(TC *tc)
Definition: mt.hh:305
void restoreThread(TC *tc)
Definition: mt.hh:154
uint64_t RegVal
Definition: types.hh:168
virtual BaseCPU * getCpuPtr()=0
virtual void setFloatReg(RegIndex reg_idx, RegVal val)=0
ThreadContext is the external interface to all thread state for anything outside of the CPU...
static RegVal readRegOtherThread(ThreadContext *tc, const RegId &reg, ThreadID tid=InvalidThreadID)
Definition: mt.hh:56
void updateTCStatusView(TC *tc)
Definition: mt.hh:323
Bitfield< 63 > val
Definition: misc.hh:771
Bitfield< 5, 0 > status
Tick curTick()
The current simulated tick.
Definition: core.hh:47
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
Definition: exec_context.hh:73
Bitfield< 4 > pc
virtual RegVal readFloatReg(RegIndex reg_idx) const =0
unsigned getVirtProcNum(TC *tc)
Definition: mt.hh:119
unsigned getTargetThread(TC *tc)
Definition: mt.hh:127
void haltThread(TC *tc)
Definition: mt.hh:135
virtual void setIntReg(RegIndex reg_idx, RegVal val)=0
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:239
Addr npc() const
Definition: types.hh:151
void forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
Definition: mt.hh:171
const ThreadID InvalidThreadID
Definition: types.hh:228
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
const RegClass & classValue() const
Class accessor.
Definition: reg_class.hh:206
virtual ThreadContext * getContext(int tn)
Given a thread num get tho thread context for it.
Definition: base.hh:298
static void setRegOtherThread(ThreadContext *tc, const RegId &reg, RegVal val, ThreadID tid=InvalidThreadID)
Definition: mt.hh:80
const RegIndex & index() const
Index accessors.
Definition: reg_class.hh:179
virtual ThreadContext * tcBase()=0
Returns a pointer to the ThreadContext.
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:79
Integer register.
Definition: reg_class.hh:57
#define warn(...)
Definition: logging.hh:212
virtual RegVal readMiscReg(RegIndex misc_reg)=0
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:208

Generated on Fri Feb 28 2020 16:26:57 for gem5 by doxygen 1.8.13