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

Generated on Sat Jun 18 2022 08:12:17 for gem5 by doxygen 1.8.17