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

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17