gem5  v22.1.0.0
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 
29 #include "arch/sparc/interrupts.hh"
30 #include "arch/sparc/isa.hh"
31 #include "arch/sparc/regs/misc.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 
40 namespace gem5
41 {
42 
43 using namespace SparcISA;
44 
45 
46 void
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
71 static 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 
91 void
92 ISA::setFSReg(int miscReg, RegVal val)
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;
103  case MISCREG_SOFTINT_CLR:
105  case MISCREG_SOFTINT_SET:
107 
108  case MISCREG_TICK_CMPR:
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 
123  case MISCREG_STICK_CMPR:
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);
168  cpu->postInterrupt(0, IT_CPU_MONDO, 0);
169  else
170  cpu->clearInterrupt(0, IT_CPU_MONDO, 0);
171  break;
174  setMiscRegNoEffect(miscReg, val);
176  cpu->postInterrupt(0, IT_DEV_MONDO, 0);
177  else
178  cpu->clearInterrupt(0, IT_DEV_MONDO, 0);
179  break;
182  setMiscRegNoEffect(miscReg, val);
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 
194  case MISCREG_HSTICK_CMPR:
195  if (hSTickCompare == NULL)
196  hSTickCompare = new HSTickCompareEvent(this);
197  setMiscRegNoEffect(miscReg, val);
198  if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
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())
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)
218  cpu->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
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 
247 RegVal
248 ISA::readFSReg(int miscReg)
249 {
250  uint64_t temp;
251 
252  switch (miscReg) {
253  /* Privileged registers. */
262  case MISCREG_SOFTINT:
263  case MISCREG_TICK_CMPR:
264  case MISCREG_STICK_CMPR:
265  case MISCREG_PIL:
266  case MISCREG_HPSTATE:
267  case MISCREG_HINTP:
268  case MISCREG_HTSTATE:
269  case MISCREG_HSTICK_CMPR:
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 
321 void
323 {
324  panic("tick compare not implemented\n");
325 }
326 
327 void
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 
351 void
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;
360  if ( tc->status() == ThreadContext::Halted)
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:186
void postInterrupt(ThreadID tid, int int_num, int index)
Definition: base.cc:194
Tick instCount()
Definition: base.hh:217
void clearInterrupt(ThreadID tid, int int_num, int index)
Definition: base.hh:238
ThreadContext * tc
Definition: isa.hh:65
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
uint64_t softint
Definition: isa.hh:66
uint64_t dev_mondo_head
Definition: isa.hh:115
STickCompareEvent * sTickCompare
Definition: isa.hh:140
uint64_t cpu_mondo_head
Definition: isa.hh:113
uint64_t res_error_head
Definition: isa.hh:117
void setMiscReg(RegIndex idx, RegVal val) override
Definition: isa.cc:766
TickCompareEvent * tickCompare
Definition: isa.hh:137
uint8_t pil
Definition: isa.hh:84
uint64_t tick
Definition: isa.hh:63
uint64_t dev_mondo_tail
Definition: isa.hh:116
HSTickCompareEvent * hSTickCompare
Definition: isa.hh:143
void checkSoftInt()
Definition: ua2005.cc:47
uint64_t cpu_mondo_tail
Definition: isa.hh:114
EventWrapper< ISA, &ISA::processSTickCompare > STickCompareEvent
Definition: isa.hh:139
uint64_t hintp
Definition: isa.hh:96
HPSTATE hpstate
Hyperprivileged Registers.
Definition: isa.hh:94
void setFSReg(int miscReg, RegVal val)
Definition: ua2005.cc:92
void processHSTickCompare()
Definition: ua2005.cc:352
uint64_t stick
Definition: isa.hh:68
uint64_t tick_cmpr
Definition: isa.hh:67
RegVal readMiscRegNoEffect(RegIndex idx) const override
Definition: isa.cc:376
uint64_t res_error_tail
Definition: isa.hh:118
uint8_t tl
Definition: isa.hh:83
uint64_t hstick_cmpr
Definition: isa.hh:98
uint64_t stick_cmpr
Definition: isa.hh:69
EventWrapper< ISA, &ISA::processHSTickCompare > HSTickCompareEvent
Definition: isa.hh:142
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
void setMiscRegNoEffect(RegIndex idx, RegVal val) override
Definition: isa.cc:585
EventWrapper< ISA, &ISA::processTickCompare > TickCompareEvent
Definition: isa.hh:136
int size() const
Definition: system.hh:213
Workload * workload
OS kernel.
Definition: system.hh:329
Threads threads
Definition: system.hh:313
virtual System * getSystemPtr()=0
@ Halted
Permanently shut down.
@ Suspended
Temporarily inactive.
virtual BaseCPU * getCpuPtr()=0
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:89
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:76
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
void deschedule(Event &event)
Definition: eventq.hh:1028
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
const char *const miscRegName[]
Definition: misc.hh:1697
Bitfield< 30, 0 > index
@ MISCREG_SOFTINT_CLR
Definition: misc.hh:54
@ MISCREG_HTBA
Definition: misc.hh:82
@ 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_PIL
Definition: misc.hh:69
@ 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_HVER
Definition: misc.hh:83
@ MISCREG_QUEUE_RES_ERROR_TAIL
Definition: misc.hh:112
@ MISCREG_QUEUE_NRES_ERROR_HEAD
Definition: misc.hh:113
const int NWindows
Definition: sparc_traits.hh:44
const int MaxTL
Definition: sparc_traits.hh:39
const int NumMiscRegs
Definition: misc.hh:175
Bitfield< 4 > x
Definition: pagetable.hh:61
Bitfield< 63 > val
Definition: misc.hh:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint16_t RegIndex
Definition: types.hh:176
static std::string getMiscRegName(RegIndex index)
Definition: ua2005.cc:72
uint64_t RegVal
Definition: types.hh:173

Generated on Wed Dec 21 2022 10:22:27 for gem5 by doxygen 1.9.1