gem5 v24.0.0.0
Loading...
Searching...
No Matches
ua2005.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
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
30#include "arch/sparc/isa.hh"
32#include "base/bitfield.hh"
33#include "base/trace.hh"
34#include "cpu/base.hh"
35#include "cpu/thread_context.hh"
36#include "debug/Quiesce.hh"
37#include "debug/Timer.hh"
38#include "sim/system.hh"
39
40namespace gem5
41{
42
43using namespace SparcISA;
44
45
46void
48{
49 BaseCPU *cpu = tc->getCpuPtr();
50
51 // If PIL < 14, copy over the tm and sm bits
52 if (pil < 14 && softint & 0x10000)
53 cpu->postInterrupt(0, IT_SOFT_INT, 16);
54 else
55 cpu->clearInterrupt(0, IT_SOFT_INT, 16);
56 if (pil < 14 && softint & 0x1)
57 cpu->postInterrupt(0, IT_SOFT_INT, 0);
58 else
59 cpu->clearInterrupt(0, IT_SOFT_INT, 0);
60
61 // Copy over any of the other bits that are set
62 for (int bit = 15; bit > 0; --bit) {
63 if (1 << bit & softint && bit > pil)
64 cpu->postInterrupt(0, IT_SOFT_INT, bit);
65 else
66 cpu->clearInterrupt(0, IT_SOFT_INT, bit);
67 }
68}
69
70// These functions map register indices to names
71static inline std::string
73{
74 static std::string miscRegName[NumMiscRegs] =
75 {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
76 "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
77 "stick", "stick_cmpr",
78 "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
79 "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
80 "wstate",*/ "gl",
81 "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
82 "hstick_cmpr",
83 "fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
84 "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
85 "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
86 "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
87 "nresErrorHead", "nresErrorTail", "TlbData" };
88 return miscRegName[index];
89}
90
91void
93{
94 BaseCPU *cpu = tc->getCpuPtr();
95
96 int64_t time;
97 switch (miscReg) {
98 /* Full system only ASRs */
99 case MISCREG_SOFTINT:
100 setMiscRegNoEffect(miscReg, val);
101 checkSoftInt();
102 break;
104 return setMiscReg(MISCREG_SOFTINT, ~val & softint);
106 return setMiscReg(MISCREG_SOFTINT, val | softint);
107
109 if (tickCompare == NULL)
110 tickCompare = new TickCompareEvent(*this);
111 setMiscRegNoEffect(miscReg, val);
112 if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
113 cpu->deschedule(tickCompare);
114 time = (tick_cmpr & mask(63)) - (tick & mask(63));
115 if (!(tick_cmpr & ~mask(63)) && time > 0) {
116 if (tickCompare->scheduled())
117 cpu->deschedule(tickCompare);
118 cpu->schedule(tickCompare, cpu->clockEdge(Cycles(time)));
119 }
120 DPRINTF(Timer, "writing to TICK compare register value %#X\n", val);
121 break;
122
124 if (sTickCompare == NULL)
125 sTickCompare = new STickCompareEvent(*this);
126 setMiscRegNoEffect(miscReg, val);
127 if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
128 cpu->deschedule(sTickCompare);
129 time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
130 cpu->instCount();
131 if (!(stick_cmpr & ~mask(63)) && time > 0) {
132 if (sTickCompare->scheduled())
133 cpu->deschedule(sTickCompare);
134 cpu->schedule(sTickCompare, cpu->clockEdge(Cycles(time)));
135 }
136 DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
137 break;
138
139 case MISCREG_PSTATE:
140 setMiscRegNoEffect(miscReg, val);
141 break;
142
143 case MISCREG_PIL:
144 setMiscRegNoEffect(miscReg, val);
145 checkSoftInt();
146 break;
147
148 case MISCREG_HVER:
149 panic("Shouldn't be writing HVER\n");
150
151 case MISCREG_HINTP:
152 setMiscRegNoEffect(miscReg, val);
153 if (hintp)
154 cpu->postInterrupt(0, IT_HINTP, 0);
155 else
156 cpu->clearInterrupt(0, IT_HINTP, 0);
157 break;
158
159 case MISCREG_HTBA:
160 // clear lower 7 bits on writes.
161 setMiscRegNoEffect(miscReg, val & ~0x7FFFULL);
162 break;
163
166 setMiscRegNoEffect(miscReg, val);
167 if (cpu_mondo_head != cpu_mondo_tail)
168 cpu->postInterrupt(0, IT_CPU_MONDO, 0);
169 else
170 cpu->clearInterrupt(0, IT_CPU_MONDO, 0);
171 break;
174 setMiscRegNoEffect(miscReg, val);
175 if (dev_mondo_head != dev_mondo_tail)
176 cpu->postInterrupt(0, IT_DEV_MONDO, 0);
177 else
178 cpu->clearInterrupt(0, IT_DEV_MONDO, 0);
179 break;
182 setMiscRegNoEffect(miscReg, val);
183 if (res_error_head != res_error_tail)
184 cpu->postInterrupt(0, IT_RES_ERROR, 0);
185 else
186 cpu->clearInterrupt(0, IT_RES_ERROR, 0);
187 break;
190 setMiscRegNoEffect(miscReg, val);
191 // This one doesn't have an interrupt to report to the guest OS
192 break;
193
195 if (hSTickCompare == NULL)
196 hSTickCompare = new HSTickCompareEvent(*this);
197 setMiscRegNoEffect(miscReg, val);
198 if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
199 cpu->deschedule(hSTickCompare);
200 time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
201 cpu->instCount();
202 if (!(hstick_cmpr & ~mask(63)) && time > 0) {
203 if (hSTickCompare->scheduled())
204 cpu->deschedule(hSTickCompare);
205 cpu->schedule(hSTickCompare, cpu->clockEdge(Cycles(time)));
206 }
207 DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
208 break;
209
210 case MISCREG_HPSTATE:
211 {
212 HPSTATE newVal = val;
213 newVal.id = 1;
214 // T1000 spec says impl. dependent val must always be 1
215 setMiscRegNoEffect(miscReg, newVal);
216 newVal = hpstate;
217 if (newVal.tlz && tl == 0 && !newVal.hpriv)
219 else
221 break;
222 }
223 case MISCREG_HTSTATE:
224 setMiscRegNoEffect(miscReg, val);
225 break;
226
228 if (bits(val,2,2))
229 panic("No support for setting spec_en bit\n");
230 setMiscRegNoEffect(miscReg, bits(val,0,0));
231 if (!bits(val,0,0)) {
232 DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
233 // Time to go to sleep
234 tc->suspend();
235 auto *workload = tc->getSystemPtr()->workload;
236 if (workload)
237 workload->recordQuiesce();
238 }
239 break;
240
241 default:
242 panic("Invalid write to FS misc register %s\n",
243 getMiscRegName(miscReg));
244 }
245}
246
247RegVal
248ISA::readFSReg(int miscReg)
249{
250 uint64_t temp;
251
252 switch (miscReg) {
253 /* Privileged registers. */
262 case MISCREG_SOFTINT:
265 case MISCREG_PIL:
266 case MISCREG_HPSTATE:
267 case MISCREG_HINTP:
268 case MISCREG_HTSTATE:
270 return readMiscRegNoEffect(miscReg) ;
271
272 case MISCREG_HTBA:
273 return readMiscRegNoEffect(miscReg) & ~0x7FFFULL;
274 case MISCREG_HVER:
275 // XXX set to match Legion
276 return 0x3eULL << 48 |
277 0x23ULL << 32 |
278 0x20ULL << 24 |
279 // MaxGL << 16 | XXX For some reason legion doesn't set GL
280 MaxTL << 8 |
281 (NWindows -1) << 0;
282
284 System *sys;
285 int x;
286 sys = tc->getSystemPtr();
287
288 temp = readMiscRegNoEffect(miscReg) & (STS::active | STS::speculative);
289 // Check that the CPU array is fully populated
290 // (by calling getNumCPus())
291 assert(sys->threads.size() > tc->contextId());
292
293 temp |= tc->contextId() << STS::shft_id;
294
295 for (x = tc->contextId() & ~3; x < sys->threads.size(); x++) {
296 switch (sys->threads[x]->status()) {
298 temp |= STS::st_run << (STS::shft_fsm0 -
299 ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
300 break;
302 // should this be idle?
303 temp |= STS::st_idle << (STS::shft_fsm0 -
304 ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
305 break;
307 temp |= STS::st_halt << (STS::shft_fsm0 -
308 ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
309 break;
310 default:
311 panic("What state are we in?!\n");
312 } // switch
313 } // for
314
315 return temp;
316 default:
317 panic("Invalid read to FS misc register\n");
318 }
319}
320
321void
323{
324 panic("tick compare not implemented\n");
325}
326
327void
329{
330 BaseCPU *cpu = tc->getCpuPtr();
331
332 // since our microcode instructions take two cycles we need to check if
333 // we're actually at the correct cycle or we need to wait a little while
334 // more
335 int delay;
336 delay = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
337 cpu->instCount();
338 assert(delay >= 0 && "stick compare missed interrupt cycle");
339
340 if (delay == 0 || tc->status() == ThreadContext::Suspended) {
341 DPRINTF(Timer, "STick compare cycle reached at %#x\n",
342 (stick_cmpr & mask(63)));
343 if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (1ULL << 63))) {
344 setMiscReg(MISCREG_SOFTINT, softint | (1ULL << 16));
345 }
346 } else {
347 cpu->schedule(sTickCompare, cpu->clockEdge(Cycles(delay)));
348 }
349}
350
351void
353{
354 BaseCPU *cpu = tc->getCpuPtr();
355
356 // since our microcode instructions take two cycles we need to check if
357 // we're actually at the correct cycle or we need to wait a little while
358 // more
359 int delay;
361 return;
362
363 delay = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
364 cpu->instCount();
365 assert(delay >= 0 && "hstick compare missed interrupt cycle");
366
367 if (delay == 0 || tc->status() == ThreadContext::Suspended) {
368 DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
369 (stick_cmpr & mask(63)));
370 if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (1ULL << 63))) {
372 }
373 // Need to do something to cause interrupt to happen here !!! @todo
374 } else {
375 cpu->schedule(hSTickCompare, cpu->clockEdge(Cycles(delay)));
376 }
377}
378
379} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
void setMiscRegNoEffect(RegIndex idx, RegVal val) override
Definition isa.cc:662
RegVal readMiscRegNoEffect(RegIndex idx) const override
Definition isa.cc:387
void setMiscReg(RegIndex, RegVal val) override
Definition isa.cc:684
void postInterrupt(ThreadID tid, int int_num, int index)
Definition base.cc:231
Tick instCount()
Definition base.hh:221
void clearInterrupt(ThreadID tid, int int_num, int index)
Definition base.hh:242
ThreadContext * tc
Definition isa.hh:68
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
Wrap a member function inside MemberEventWrapper to use it as an event callback.
Definition eventq.hh:1092
void checkSoftInt()
Definition ua2005.cc:47
void setFSReg(int miscReg, RegVal val)
Definition ua2005.cc:92
void processHSTickCompare()
Definition ua2005.cc:352
void processSTickCompare()
Definition ua2005.cc:328
void processTickCompare()
Process a tick compare event and generate an interrupt on the cpu if appropriate.
Definition ua2005.cc:322
RegVal readFSReg(int miscReg)
Definition ua2005.cc:248
int size() const
Definition system.hh:210
Workload * workload
OS kernel.
Definition system.hh:326
Threads threads
Definition system.hh:310
virtual System * getSystemPtr()=0
virtual BaseCPU * getCpuPtr()=0
@ Halted
Permanently shut down.
@ Suspended
Temporarily inactive.
virtual Status status() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual ContextID contextId() const =0
virtual void suspend()=0
Set the status to Suspended.
void recordQuiesce()
Definition workload.hh:90
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
void deschedule(Event &event)
Definition eventq.hh:1021
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
const char *const miscRegName[]
Definition misc.hh:1815
Bitfield< 23, 20 > tl
Bitfield< 30, 0 > index
Bitfield< 3 > x
Definition pagetable.hh:73
@ MISCREG_SOFTINT_CLR
Definition misc.hh:54
@ MISCREG_QUEUE_RES_ERROR_HEAD
Definition misc.hh:111
@ MISCREG_HPSTATE
Hyper privileged registers.
Definition misc.hh:79
@ MISCREG_PSTATE
Definition misc.hh:67
@ MISCREG_QUEUE_DEV_MONDO_TAIL
Definition misc.hh:110
@ MISCREG_QUEUE_CPU_MONDO_HEAD
Definition misc.hh:107
@ MISCREG_STICK_CMPR
Definition misc.hh:58
@ MISCREG_QUEUE_NRES_ERROR_TAIL
Definition misc.hh:114
@ MISCREG_TICK_CMPR
Definition misc.hh:56
@ MISCREG_HTSTATE
Definition misc.hh:80
@ MISCREG_HINTP
Definition misc.hh:81
@ MISCREG_HSTICK_CMPR
Definition misc.hh:85
@ MISCREG_QUEUE_CPU_MONDO_TAIL
Definition misc.hh:108
@ MISCREG_SOFTINT_SET
Definition misc.hh:53
@ MISCREG_QUEUE_DEV_MONDO_HEAD
Definition misc.hh:109
@ MISCREG_STRAND_STS_REG
Definition misc.hh:84
@ MISCREG_SOFTINT
Definition misc.hh:55
@ MISCREG_QUEUE_RES_ERROR_TAIL
Definition misc.hh:112
@ MISCREG_QUEUE_NRES_ERROR_HEAD
Definition misc.hh:113
const int NWindows
const int MaxTL
const int NumMiscRegs
Definition misc.hh:175
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint16_t RegIndex
Definition types.hh:176
uint64_t RegVal
Definition types.hh:173
static std::string getMiscRegName(RegIndex index)
Definition ua2005.cc:72

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0