gem5 v24.0.0.0
Loading...
Searching...
No Matches
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/int.hh"
46#include "base/bitfield.hh"
47#include "base/logging.hh"
48#include "base/trace.hh"
49#include "cpu/exec_context.hh"
50
51namespace gem5
52{
53
54namespace MipsISA
55{
56
57static inline RegVal
60{
61 ThreadContext *otc = nullptr;
62 if (tid != InvalidThreadID)
63 otc = tc->getCpuPtr()->getContext(tid);
64 else
65 otc = tc;
66
67 switch (reg.classValue()) {
68 case IntRegClass:
69 case FloatRegClass:
70 return otc->getReg(reg);
71 break;
72 case MiscRegClass:
73 return otc->readMiscReg(reg.index());
74 default:
75 panic("Unexpected reg class! (%s)", reg.className());
76 }
77}
78
79static 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 case FloatRegClass:
92 otc->setReg(reg, 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
101static inline RegVal
104{
105 return readRegOtherThread(xc->tcBase(), reg, tid);
106}
107
108static inline void
114
115template <class TC>
116inline unsigned
118{
119 TCBindReg tcbind = tc->readMiscRegNoEffect(misc_reg::TcBind);
120 return tcbind.curVPE;
121}
122
123template <class TC>
124inline unsigned
126{
127 VPEControlReg vpeCtrl = tc->readMiscRegNoEffect(misc_reg::VpeControl);
128 return vpeCtrl.targTC;
129}
130
131template <class TC>
132inline void
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 auto &pc = tc->pcState().template as<MipsISA::PCState>();
142 tc->setMiscReg(misc_reg::TcRestart, 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
150template <class TC>
151inline void
153{
154 if (tc->status() != TC::Active) {
155 // Restore PC from TCRestart
156 Addr restartPC = tc->readMiscRegNoEffect(misc_reg::TcRestart);
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
167template <class TC>
168void
169forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
170{
171 MVPConf0Reg mvpConf = tc->readMiscRegNoEffect(misc_reg::MvpConf0);
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(misc_reg::TcBind);
179
180 if (tidTCBind.curVPE == tcBind.curVPE) {
181
182 TCStatusReg tidTCStatus =
184
185 TCHaltReg tidTCHalt =
187
188 if (tidTCStatus.da == 1 && tidTCHalt.h == 0 &&
189 tidTCStatus.a == 0 && success == 0) {
190
192 tid);
193 setRegOtherThread(tc, intRegClass[Rd_bits], Rt, tid);
194
195 StatusReg status = tc->readMiscReg(misc_reg::Status);
196 TCStatusReg tcStatus = tc->readMiscReg(misc_reg::TcStatus);
197
198 // Set Run-State to Running
199 tidTCStatus.rnst = 0;
200 // Set Delay-Slot to 0
201 tidTCStatus.tds = 0;
202 // Set Dirty TC to 1
203 tidTCStatus.dt = 1;
204 // Set Activated to 1
205 tidTCStatus.a = 1;
206 // Set status to previous thread's status
207 tidTCStatus.tksu = status.ksu;
208 // Set ASID to previous thread's state
209 tidTCStatus.asid = tcStatus.asid;
210
211 // Write Status Register
213 tidTCStatus, tid);
214
215 // Mark As Successful Fork
216 success = 1;
217 }
218 } else {
219 std::cerr << "Bad VPEs" << std::endl;
220 }
221 }
222
223 if (success == 0) {
224 VPEControlReg vpeControl =
225 tc->readMiscRegNoEffect(misc_reg::VpeControl);
226 vpeControl.excpt = 1;
227 tc->setMiscReg(misc_reg::VpeControl, vpeControl);
228 fault = std::make_shared<ThreadFault>();
229 }
230}
231
232
233template <class TC>
234int
235yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
236{
237 if (src_reg == 0) {
238 MVPConf0Reg mvpConf0 = tc->readMiscRegNoEffect(misc_reg::MvpConf0);
239 ThreadID num_threads = mvpConf0.ptc + 1;
240
241 int ok = 0;
242
243 // Get Current VPE & TC numbers from calling thread
244 TCBindReg tcBind = tc->readMiscRegNoEffect(misc_reg::TcBind);
245
246 for (ThreadID tid = 0; tid < num_threads; tid++) {
247 TCStatusReg tidTCStatus =
249 TCHaltReg tidTCHalt =
251 TCBindReg tidTCBind =
253
254 if (tidTCBind.curVPE == tcBind.curVPE &&
255 tidTCBind.curTC == tcBind.curTC &&
256 tidTCStatus.da == 1 &&
257 tidTCHalt.h == 0 &&
258 tidTCStatus.a == 1) {
259 ok = 1;
260 }
261 }
262
263 if (ok == 1) {
264 TCStatusReg tcStatus = tc->readMiscRegNoEffect(misc_reg::TcStatus);
265 tcStatus.a = 0;
266 tc->setMiscReg(misc_reg::TcStatus, tcStatus);
267 warn("%i: Deactivating Hardware Thread Context #%i",
268 curTick(), tc->threadId());
269 }
270 } else if (src_reg > 0) {
271 if ((src_reg & ~yield_mask) != 0) {
272 VPEControlReg vpeControl = tc->readMiscReg(misc_reg::VpeControl);
273 vpeControl.excpt = 2;
274 tc->setMiscReg(misc_reg::VpeControl, vpeControl);
275 fault = std::make_shared<ThreadFault>();
276 } else {
277 }
278 } else if (src_reg != -2) {
279 TCStatusReg tcStatus = tc->readMiscRegNoEffect(misc_reg::TcStatus);
280 VPEControlReg vpeControl =
281 tc->readMiscRegNoEffect(misc_reg::VpeControl);
282
283 if (vpeControl.ysi == 1 && tcStatus.dt == 1 ) {
284 vpeControl.excpt = 4;
285 fault = std::make_shared<ThreadFault>();
286 } else {
287 }
288 }
289
290 return src_reg & yield_mask;
291}
292
293
294// TC will usually be a object derived from ThreadContext
295// (src/cpu/thread_context.hh)
296template <class TC>
297inline void
299{
300 // TCStatus' register view must be the same as
301 // Status register view for CU, MX, KSU bits
302 TCStatusReg tcStatus = tc->readMiscRegNoEffect(misc_reg::TcStatus);
303 StatusReg status = tc->readMiscRegNoEffect(misc_reg::Status);
304
305 status.cu = tcStatus.tcu;
306 status.mx = tcStatus.tmx;
307 status.ksu = tcStatus.tksu;
308
309 tc->setMiscRegNoEffect(misc_reg::Status, status);
310}
311
312// TC will usually be a object derived from ThreadContext
313// (src/cpu/thread_context.hh)
314template <class TC>
315inline void
317{
318 // TCStatus' register view must be the same as
319 // Status register view for CU, MX, KSU bits
320 TCStatusReg tcStatus = tc->readMiscRegNoEffect(misc_reg::TcStatus);
321 StatusReg status = tc->readMiscRegNoEffect(misc_reg::Status);
322
323 tcStatus.tcu = status.cu;
324 tcStatus.tmx = status.mx;
325 tcStatus.tksu = status.ksu;
326
327 tc->setMiscRegNoEffect(misc_reg::TcStatus, tcStatus);
328}
329
330} // namespace MipsISA
331} // namespace gem5
332
333#endif
virtual ThreadContext * getContext(int tn)
Given a thread num get tho thread context for it.
Definition base.hh:288
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
virtual ThreadContext * tcBase() const =0
Returns a pointer to the ThreadContext.
Register ID: describe an architectural register with its class and index.
Definition reg_class.hh:94
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual RegVal getReg(const RegId &reg) const
virtual BaseCPU * getCpuPtr()=0
virtual void setReg(const RegId &reg, RegVal val)
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define warn(...)
Definition logging.hh:256
Bitfield< 5, 0 > status
constexpr RegClass intRegClass
Definition int.hh:173
Bitfield< 36 > as
constexpr RegClass miscRegClass
Definition misc.hh:2937
void restoreThread(TC *tc)
Definition mt.hh:152
unsigned getTargetThread(TC *tc)
Definition mt.hh:125
Bitfield< 4 > pc
unsigned getVirtProcNum(TC *tc)
Definition mt.hh:117
void updateTCStatusView(TC *tc)
Definition mt.hh:316
static RegVal readRegOtherThread(ThreadContext *tc, const RegId &reg, ThreadID tid=InvalidThreadID)
Definition mt.hh:58
int yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
Definition mt.hh:235
void haltThread(TC *tc)
Definition mt.hh:133
void forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
Definition mt.hh:169
static void setRegOtherThread(ThreadContext *tc, const RegId &reg, RegVal val, ThreadID tid=InvalidThreadID)
Definition mt.hh:80
void updateStatusView(TC *tc)
Definition mt.hh:298
Bitfield< 5, 3 > reg
Definition types.hh:92
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
uint64_t RegVal
Definition types.hh:173
const ThreadID InvalidThreadID
Definition types.hh:236
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
@ FloatRegClass
Floating-point register.
Definition reg_class.hh:62
@ IntRegClass
Integer register.
Definition reg_class.hh:61
@ MiscRegClass
Control (misc) register.
Definition reg_class.hh:70

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0