gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
faults.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003-2005 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/faults.hh"
30 
31 #include <algorithm>
32 
33 #include "arch/sparc/mmu.hh"
34 #include "arch/sparc/process.hh"
37 #include "arch/sparc/types.hh"
38 #include "base/bitfield.hh"
39 #include "base/compiler.hh"
40 #include "base/trace.hh"
41 #include "cpu/base.hh"
42 #include "cpu/thread_context.hh"
43 #include "mem/page_table.hh"
44 #include "sim/full_system.hh"
45 #include "sim/process.hh"
46 
47 namespace gem5
48 {
49 
50 namespace SparcISA
51 {
52 
55 ("power_on_reset", 0x001, 0, {{H, H, H}});
56 
59 ("watch_dog_reset", 0x002, 120, {{H, H, H}});
60 
63 ("externally_initiated_reset", 0x003, 110, {{H, H, H}});
64 
67 ("software_initiated_reset", 0x004, 130, {{SH, SH, H}});
68 
71 ("RED_state_exception", 0x005, 1, {{H, H, H}});
72 
75 ("store_error", 0x007, 201, {{H, H, H}});
76 
79 ("instruction_access_exception", 0x008, 300, {{H, H, H}});
80 
81 //XXX This trap is apparently dropped from ua2005
82 /*template<> SparcFaultBase::FaultVals
83  SparcFault<InstructionAccessMMUMiss>::vals
84  ("inst_mmu", 0x009, 2, {{H, H, H}});*/
85 
88 ("instruction_access_error", 0x00A, 400, {{H, H, H}});
89 
92 ("illegal_instruction", 0x010, 620, {{H, H, H}});
93 
96 ("privileged_opcode", 0x011, 700, {{P, SH, SH}});
97 
98 //XXX This trap is apparently dropped from ua2005
99 /*template<> SparcFaultBase::FaultVals
100  SparcFault<UnimplementedLDD>::vals
101  ("unimp_ldd", 0x012, 6, {{H, H, H}});*/
102 
103 //XXX This trap is apparently dropped from ua2005
104 /*template<> SparcFaultBase::FaultVals
105  SparcFault<UnimplementedSTD>::vals
106  ("unimp_std", 0x013, 6, {{H, H, H}});*/
107 
108 template<> SparcFaultBase::FaultVals
110 ("fp_disabled", 0x020, 800, {{P, P, H}});
111 
112 /* SPARCv8 and SPARCv9 define just fp_disabled trap. SIMD is not contemplated
113  * as a separate part. Therefore, we use the same code and TT */
114 template<> SparcFaultBase::FaultVals
116 ("fp_disabled", 0x020, 800, {{P, P, H}});
117 
118 template<> SparcFaultBase::FaultVals
120 ("fp_exception_ieee_754", 0x021, 1110, {{P, P, H}});
121 
122 template<> SparcFaultBase::FaultVals
124 ("fp_exception_other", 0x022, 1110, {{P, P, H}});
125 
126 template<> SparcFaultBase::FaultVals
128 ("tag_overflow", 0x023, 1400, {{P, P, H}});
129 
130 template<> SparcFaultBase::FaultVals
132 ("clean_window", 0x024, 1010, {{P, P, H}});
133 
134 template<> SparcFaultBase::FaultVals
136 ("division_by_zero", 0x028, 1500, {{P, P, H}});
137 
138 template<> SparcFaultBase::FaultVals
140 ("internal_processor_error", 0x029, 4, {{H, H, H}});
141 
142 template<> SparcFaultBase::FaultVals
144 ("instruction_invalid_tsb_entry", 0x02A, 210, {{H, H, SH}});
145 
146 template<> SparcFaultBase::FaultVals
148 ("data_invalid_tsb_entry", 0x02B, 1203, {{H, H, H}});
149 
150 template<> SparcFaultBase::FaultVals
152 ("data_access_exception", 0x030, 1201, {{H, H, H}});
153 
154 //XXX This trap is apparently dropped from ua2005
155 /*template<> SparcFaultBase::FaultVals
156  SparcFault<DataAccessMMUMiss>::vals
157  ("data_mmu", 0x031, 12, {{H, H, H}});*/
158 
159 template<> SparcFaultBase::FaultVals
161 ("data_access_error", 0x032, 1210, {{H, H, H}});
162 
163 template<> SparcFaultBase::FaultVals
165 ("data_access_protection", 0x033, 1207, {{H, H, H}});
166 
167 template<> SparcFaultBase::FaultVals
169 ("mem_address_not_aligned", 0x034, 1020, {{H, H, H}});
170 
171 template<> SparcFaultBase::FaultVals
173 ("LDDF_mem_address_not_aligned", 0x035, 1010, {{H, H, H}});
174 
175 template<> SparcFaultBase::FaultVals
177 ("STDF_mem_address_not_aligned", 0x036, 1010, {{H, H, H}});
178 
179 template<> SparcFaultBase::FaultVals
181 ("privileged_action", 0x037, 1110, {{H, H, SH}});
182 
183 template<> SparcFaultBase::FaultVals
185 ("LDQF_mem_address_not_aligned", 0x038, 1010, {{H, H, H}});
186 
187 template<> SparcFaultBase::FaultVals
189 ("STQF_mem_address_not_aligned", 0x039, 1010, {{H, H, H}});
190 
191 template<> SparcFaultBase::FaultVals
193 ("instruction_real_translation_miss", 0x03E, 208, {{H, H, SH}});
194 
195 template<> SparcFaultBase::FaultVals
197 ("data_real_translation_miss", 0x03F, 1203, {{H, H, H}});
198 
199 //XXX This trap is apparently dropped from ua2005
200 /*template<> SparcFaultBase::FaultVals
201  SparcFault<AsyncDataError>::vals
202  ("async_data", 0x040, 2, {{H, H, H}});*/
203 
204 template<> SparcFaultBase::FaultVals
206 ("interrupt_level_n", 0x040, 0, {{P, P, SH}});
207 
208 template<> SparcFaultBase::FaultVals
210 ("hstick_match", 0x05E, 1601, {{H, H, H}});
211 
212 template<> SparcFaultBase::FaultVals
214 ("trap_level_zero", 0x05F, 202, {{H, H, SH}});
215 
216 template<> SparcFaultBase::FaultVals
218 ("interrupt_vector", 0x060, 2630, {{H, H, H}});
219 
220 template<> SparcFaultBase::FaultVals
222 ("PA_watchpoint", 0x061, 1209, {{H, H, H}});
223 
224 template<> SparcFaultBase::FaultVals
226 ("VA_watchpoint", 0x062, 1120, {{P, P, SH}});
227 
228 template<> SparcFaultBase::FaultVals
230 ("fast_instruction_access_MMU_miss", 0x064, 208, {{H, H, SH}});
231 
232 template<> SparcFaultBase::FaultVals
234 ("fast_data_access_MMU_miss", 0x068, 1203, {{H, H, H}});
235 
236 template<> SparcFaultBase::FaultVals
238 ("fast_data_access_protection", 0x06C, 1207, {{H, H, H}});
239 
240 template<> SparcFaultBase::FaultVals
242 ("instruction_break", 0x076, 610, {{H, H, H}});
243 
244 template<> SparcFaultBase::FaultVals
246 ("cpu_mondo", 0x07C, 1608, {{P, P, SH}});
247 
248 template<> SparcFaultBase::FaultVals
250 ("dev_mondo", 0x07D, 1611, {{P, P, SH}});
251 
252 template<> SparcFaultBase::FaultVals
254 ("resume_error", 0x07E, 3330, {{P, P, SH}});
255 
256 template<> SparcFaultBase::FaultVals
258 ("spill_n_normal", 0x080, 900, {{P, P, H}});
259 
260 template<> SparcFaultBase::FaultVals
262 ("spill_n_other", 0x0A0, 900, {{P, P, H}});
263 
264 template<> SparcFaultBase::FaultVals
266 ("fill_n_normal", 0x0C0, 900, {{P, P, H}});
267 
268 template<> SparcFaultBase::FaultVals
270 ("fill_n_other", 0x0E0, 900, {{P, P, H}});
271 
272 template<> SparcFaultBase::FaultVals
274 ("trap_instruction", 0x100, 1602, {{P, P, H}});
275 
281 void
283 {
284  //@todo Disable the mmu?
285  //@todo Disable watchpoints?
286  HPSTATE hpstate= tc->readMiscRegNoEffect(MISCREG_HPSTATE);
287  hpstate.red = 1;
288  hpstate.hpriv = 1;
289  tc->setMiscReg(MISCREG_HPSTATE, hpstate);
290  // PSTATE.priv is set to 1 here. The manual says it should be 0, but
291  // Legion sets it to 1.
292  PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
293  pstate.priv = 1;
294  tc->setMiscReg(MISCREG_PSTATE, pstate);
295 }
296 
302 void
304 {
306  PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
307  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
308  CCR ccr = tc->getReg(int_reg::Ccr);
311  RegVal CANSAVE = tc->getReg(int_reg::Cansave);
313  auto &pc = tc->pcState().as<PCState>();
314 
315  Addr pcMask = pstate.am ? mask(32) : mask(64);
316 
317  // set TSTATE.gl to gl
318  replaceBits(TSTATE, 42, 40, GL);
319  // set TSTATE.ccr to ccr
320  replaceBits(TSTATE, 39, 32, ccr);
321  // set TSTATE.asi to asi
322  replaceBits(TSTATE, 31, 24, ASI);
323  // set TSTATE.pstate to pstate
324  replaceBits(TSTATE, 20, 8, pstate);
325  // set TSTATE.cwp to cwp
326  replaceBits(TSTATE, 4, 0, CWP);
327 
328  // Write back TSTATE
329  tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
330 
331  // set TPC to PC
332  tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
333  // set TNPC to NPC
334  tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
335 
336  // set HTSTATE.hpstate to hpstate
337  tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
338 
339  // TT = trap type;
341 
342  // Update GL
343  tc->setMiscReg(MISCREG_GL, std::min<int>(GL+1, MaxGL));
344 
345  bool priv = pstate.priv; // just save the priv bit
346  pstate = 0;
347  pstate.priv = priv;
348  pstate.pef = 1;
349  tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
350 
351  hpstate.red = 1;
352  hpstate.hpriv = 1;
353  hpstate.ibe = 0;
354  hpstate.tlz = 0;
355  tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
356 
357  bool changedCWP = true;
358  if (tt == 0x24)
359  CWP++;
360  else if (0x80 <= tt && tt <= 0xbf)
361  CWP += (CANSAVE + 2);
362  else if (0xc0 <= tt && tt <= 0xff)
363  CWP--;
364  else
365  changedCWP = false;
366 
367  if (changedCWP) {
368  CWP = (CWP + NWindows) % NWindows;
369  tc->setMiscReg(MISCREG_CWP, CWP);
370  }
371 }
372 
378 void
379 doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
380 {
383  PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
384  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
385  CCR ccr = tc->getReg(int_reg::Ccr);
388  RegVal CANSAVE = tc->getReg(int_reg::Cansave);
390  auto &pc = tc->pcState().as<PCState>();
391 
392  // Increment the trap level
393  TL++;
395 
396  Addr pcMask = pstate.am ? mask(32) : mask(64);
397 
398  // Save off state
399 
400  // set TSTATE.gl to gl
401  replaceBits(TSTATE, 42, 40, GL);
402  // set TSTATE.ccr to ccr
403  replaceBits(TSTATE, 39, 32, ccr);
404  // set TSTATE.asi to asi
405  replaceBits(TSTATE, 31, 24, ASI);
406  // set TSTATE.pstate to pstate
407  replaceBits(TSTATE, 20, 8, pstate);
408  // set TSTATE.cwp to cwp
409  replaceBits(TSTATE, 4, 0, CWP);
410 
411  // Write back TSTATE
412  tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
413 
414  // set TPC to PC
415  tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
416  // set TNPC to NPC
417  tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
418 
419  // set HTSTATE.hpstate to hpstate
420  tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
421 
422  // TT = trap type;
424 
425  // Update the global register level
426  if (!gotoHpriv)
427  tc->setMiscReg(MISCREG_GL, std::min<int>(GL + 1, MaxPGL));
428  else
429  tc->setMiscReg(MISCREG_GL, std::min<int>(GL + 1, MaxGL));
430 
431  // pstate.mm is unchanged
432  pstate.pef = 1; // PSTATE.pef = whether or not an fpu is present
433  pstate.am = 0;
434  pstate.ie = 0;
435  // pstate.tle is unchanged
436  // pstate.tct = 0
437 
438  if (gotoHpriv) {
439  pstate.cle = 0;
440  // The manual says PSTATE.priv should be 0, but Legion leaves it alone
441  hpstate.red = 0;
442  hpstate.hpriv = 1;
443  hpstate.ibe = 0;
444  // hpstate.tlz is unchanged
445  tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
446  } else { // we are going to priv
447  pstate.priv = 1;
448  pstate.cle = pstate.tle;
449  }
450  tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
451 
452 
453  bool changedCWP = true;
454  if (tt == 0x24)
455  CWP++;
456  else if (0x80 <= tt && tt <= 0xbf)
457  CWP += (CANSAVE + 2);
458  else if (0xc0 <= tt && tt <= 0xff)
459  CWP--;
460  else
461  changedCWP = false;
462 
463  if (changedCWP) {
464  CWP = (CWP + NWindows) % NWindows;
465  tc->setMiscReg(MISCREG_CWP, CWP);
466  }
467 }
468 
469 void
470 getREDVector(RegVal TT, Addr &PC, Addr &NPC)
471 {
472  //XXX The following constant might belong in a header file.
473  const Addr RSTVAddr = 0xFFF0000000ULL;
474  PC = RSTVAddr | ((TT << 5) & 0xFF);
475  NPC = PC + sizeof(MachInst);
476 }
477 
478 void
480 {
482  PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
483  NPC = PC + sizeof(MachInst);
484 }
485 
486 void
488 {
490  PC = (TBA & ~mask(15)) |
491  (TL > 1 ? (1 << 14) : 0) |
492  ((TT << 5) & mask(14));
493  NPC = PC + sizeof(MachInst);
494 }
495 
496 void
498 {
499  FaultBase::invoke(tc);
500  if (!FullSystem)
501  return;
502 
503 
504  // We can refer to this to see what the trap level -was-, but something
505  // in the middle could change it in the regfile out from under us.
508  PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
509  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
510 
511  Addr PC, NPC;
512 
513  PrivilegeLevel current;
514  if (hpstate.hpriv)
515  current = Hyperprivileged;
516  else if (pstate.priv)
517  current = Privileged;
518  else
519  current = User;
520 
521  PrivilegeLevel level = getNextLevel(current);
522 
523  if (hpstate.red || (tl == MaxTL - 1)) {
524  getREDVector(5, PC, NPC);
525  doREDFault(tc, tt);
526  // This changes the hpstate and pstate, so we need to make sure we
527  // save the old version on the trap stack in doREDFault.
528  enterREDState(tc);
529  } else if (tl == MaxTL) {
530  panic("Should go to error state here.. crap\n");
531  // Do error_state somehow?
532  // Probably inject a WDR fault using the interrupt mechanism.
533  // What should the PC and NPC be set to?
534  } else if (tl > MaxPTL && level == Privileged) {
535  // guest_watchdog fault
536  doNormalFault(tc, trapType(), true);
537  getHyperVector(tc, PC, NPC, 2);
538  } else if (level == Hyperprivileged ||
539  (level == Privileged && trapType() >= 384)) {
540  doNormalFault(tc, trapType(), true);
541  getHyperVector(tc, PC, NPC, trapType());
542  } else {
543  doNormalFault(tc, trapType(), false);
544  getPrivVector(tc, PC, NPC, trapType(), tl + 1);
545  }
546 
547  PCState pc;
548  pc.pc(PC);
549  pc.npc(NPC);
550  pc.nnpc(NPC + sizeof(MachInst));
551  pc.upc(0);
552  pc.nupc(1);
553  tc->pcState(pc);
554 }
555 
556 void
558 {
559  // For SPARC, when a system is first started, there is a power
560  // on reset Trap which sets the processor into the following state.
561  // Bits that aren't set aren't defined on startup.
562 
566 
567  PSTATE pstate = 0;
568  pstate.pef = 1;
569  pstate.priv = 1;
570  tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
571 
572  // Turn on red and hpriv, set everything else to 0
573  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
574  hpstate.red = 1;
575  hpstate.hpriv = 1;
576  hpstate.ibe = 0;
577  hpstate.tlz = 0;
578  tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
579 
580  // The tick register is unreadable by nonprivileged software
581  tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
582 
583  // Enter RED state. We do this last so that the actual state preserved in
584  // the trap stack is the state from before this fault.
585  enterREDState(tc);
586 
587  Addr PC, NPC;
588  getREDVector(trapType(), PC, NPC);
589 
590  PCState pc;
591  pc.pc(PC);
592  pc.npc(NPC);
593  pc.nnpc(NPC + sizeof(MachInst));
594  pc.upc(0);
595  pc.nupc(1);
596  tc->pcState(pc);
597 
598  // These registers are specified as "undefined" after a POR, and they
599  // should have reasonable values after the miscregfile is reset
600  /*
601  // Clear all the soft interrupt bits
602  softint = 0;
603  // disable timer compare interrupts, reset tick_cmpr
604  tc->setMiscRegNoEffect(MISCREG_
605  tick_cmprFields.int_dis = 1;
606  tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
607  stickFields.npt = 1; // The TICK register is unreadable by by !priv
608  stick_cmprFields.int_dis = 1; // disable timer compare interrupts
609  stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
610 
611  tt[tl] = _trapType;
612 
613  hintp = 0; // no interrupts pending
614  hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
615  hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
616  */
617 }
618 
619 void
621  const StaticInstPtr &inst)
622 {
623  if (FullSystem) {
624  SparcFaultBase::invoke(tc, inst);
625  return;
626  }
627 
628  Process *p = tc->getProcessPtr();
629  const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
630  panic_if(!pte, "Tried to execute unmapped address %#x.\n", vaddr);
631 
632  Addr alignedvaddr = p->pTable->pageAlign(vaddr);
633 
634  // Grab fields used during instruction translation to figure out
635  // which context to use.
636  uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
637 
638  // Inside a VM, a real address is the address that guest OS would
639  // interpret to be a physical address. To map to the physical address,
640  // it still needs to undergo a translation. The instruction
641  // translation code in the SPARC ITLB code assumes that the context is
642  // zero (kernel-level) if real addressing is being used.
643  bool is_real_address = !bits(tlbdata, 4);
644 
645  // The SPARC ITLB code assumes that traps are executed in context
646  // zero so we carry that assumption through here.
647  bool trapped = bits(tlbdata, 18, 16) > 0;
648 
649  // The primary context acts as a PASID. It allows the MMU to
650  // distinguish between virtual addresses that would alias to the
651  // same physical address (if two or more processes shared the same
652  // virtual address mapping).
653  int primary_context = bits(tlbdata, 47, 32);
654 
655  // The partition id distinguishes between virtualized environments.
656  int const partition_id = 0;
657 
658  // Given the assumptions in the translateInst code in the SPARC ITLB,
659  // the logic works out to the following for the context.
660  int context_id = (is_real_address || trapped) ? 0 : primary_context;
661 
662  TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr,
665 
666  // Insert the TLB entry.
667  // The entry specifying whether the address is "real" is set to
668  // false for syscall emulation mode regardless of whether the
669  // address is real in preceding code. Not sure sure that this is
670  // correct, but also not sure if it matters at all.
671  static_cast<MMU *>(tc->getMMUPtr())->insertItlbEntry(
672  alignedvaddr, partition_id, context_id,
673  false, entry.pte);
674 }
675 
676 void
678 {
679  if (FullSystem) {
680  SparcFaultBase::invoke(tc, inst);
681  return;
682  }
683 
684  Process *p = tc->getProcessPtr();
685  const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
686  if (!pte && p->fixupFault(vaddr))
687  pte = p->pTable->lookup(vaddr);
688  panic_if(!pte, "Tried to access unmapped address %#x.\n", vaddr);
689 
690  Addr alignedvaddr = p->pTable->pageAlign(vaddr);
691 
692  // Grab fields used during data translation to figure out
693  // which context to use.
694  uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
695 
696  // The primary context acts as a PASID. It allows the MMU to
697  // distinguish between virtual addresses that would alias to the
698  // same physical address (if two or more processes shared the same
699  // virtual address mapping). There's a secondary context used in the
700  // DTLB translation code, but it should __probably__ be zero for
701  // syscall emulation code. (The secondary context is used by Solaris
702  // to allow kernel privilege code to access user space code:
703  // [ISBN 0-13-022496-0]:PG199.)
704  int primary_context = bits(tlbdata, 47, 32);
705 
706  // "Hyper-Privileged Mode" is in use. There are three main modes of
707  // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
708  // User Mode.
709  int hpriv = bits(tlbdata, 0);
710 
711  // Reset, Error and Debug state is in use. Something horrible has
712  // happened or the system is operating in Reset Mode.
713  int red = bits(tlbdata, 1);
714 
715  // Inside a VM, a real address is the address that guest OS would
716  // interpret to be a physical address. To map to the physical address,
717  // it still needs to undergo a translation. The instruction
718  // translation code in the SPARC ITLB code assumes that the context is
719  // zero (kernel-level) if real addressing is being used.
720  int is_real_address = !bits(tlbdata, 5);
721 
722  // Grab the address space identifier register from the thread context.
723  // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
724  // MISCREG_ASI causes me to think that the ASI register implementation
725  // might be bugged. The NoEffect variant changes the ASI register
726  // value in the architectural state while the normal variant changes
727  // the context field in the thread context's currently decoded request
728  // but does not directly affect the ASI register value in the
729  // architectural state. The ASI values and the context field in the
730  // request packet seem to have completely different uses.
731  RegVal reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
732  ASI asi = static_cast<ASI>(reg_asi);
733 
734  // The SPARC DTLB code assumes that traps are executed in context
735  // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
736  // an assumption that the nucleus address space is being used, but
737  // the context is the relevant issue since we need to pass it to TLB.
738  bool trapped = bits(tlbdata, 18, 16) > 0;
739 
740  // Given the assumptions in the translateData code in the SPARC DTLB,
741  // the logic works out to the following for the context.
742  int context_id = ((!hpriv && !red && is_real_address) ||
743  asiIsReal(asi) ||
744  (trapped && asi == ASI_IMPLICIT))
745  ? 0 : primary_context;
746 
747  // The partition id distinguishes between virtualized environments.
748  int const partition_id = 0;
749 
750  TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr,
753 
754  // Insert the TLB entry.
755  // The entry specifying whether the address is "real" is set to
756  // false for syscall emulation mode regardless of whether the
757  // address is real in preceding code. Not sure sure that this is
758  // correct, but also not sure if it matters at all.
759  static_cast<MMU *>(tc->getMMUPtr())->insertDtlbEntry(
760  alignedvaddr, partition_id, context_id,
761  false, entry.pte);
762 }
763 
764 void
766 {
767  if (FullSystem) {
768  SparcFaultBase::invoke(tc, inst);
769  return;
770  }
771 
772  doNormalFault(tc, trapType(), false);
773 
774  Process *p = tc->getProcessPtr();
775 
776  SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
777  assert(sp);
778 
779  // Then adjust the PC and NPC
780  tc->pcState(sp->readSpillStart());
781 }
782 
783 void
785 {
786  if (FullSystem) {
787  SparcFaultBase::invoke(tc, inst);
788  return;
789  }
790 
791  doNormalFault(tc, trapType(), false);
792 
793  Process *p = tc->getProcessPtr();
794 
795  SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
796  assert(sp);
797 
798  // Then adjust the PC and NPC
799  tc->pcState(sp->readFillStart());
800 }
801 
802 void
804 {
805  if (FullSystem) {
806  SparcFaultBase::invoke(tc, inst);
807  return;
808  }
809 
810  // In SE, this mechanism is how the process requests a service from
811  // the operating system. We'll get the process object from the thread
812  // context and let it service the request.
813 
814  Process *p = tc->getProcessPtr();
815 
816  [[maybe_unused]] SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
817  assert(sp);
818 
819  auto *workload = dynamic_cast<SEWorkload *>(tc->getSystemPtr()->workload);
820  workload->handleTrap(tc, _n);
821 
822  // We need to explicitly advance the pc, since that's not done for us
823  // on a faulting instruction
824  PCState pc = tc->pcState().as<PCState>();
825  pc.advance();
826  tc->pcState(pc);
827 }
828 
829 } // namespace SparcISA
830 } // namespace gem5
gem5::SparcISA::EnumeratedFault< SpillNNormal >::trapType
TrapType trapType()
Definition: faults.hh:185
gem5::EmulationPageTable::Entry::flags
uint64_t flags
Definition: page_table.hh:59
gem5::X86ISA::level
Bitfield< 20 > level
Definition: intmessage.hh:51
gem5::SparcISA::MISCREG_ASI
@ MISCREG_ASI
Ancillary State Registers.
Definition: misc.hh:47
gem5::SparcISA::SparcFaultBase::Hyperprivileged
@ Hyperprivileged
Definition: faults.hh:56
gem5::ThreadContext::getSystemPtr
virtual System * getSystemPtr()=0
gem5::SparcISA::MMU
Definition: mmu.hh:52
gem5::SparcISA::SparcFaultBase::trapType
virtual TrapType trapType()=0
gem5::RegVal
uint64_t RegVal
Definition: types.hh:173
process.hh
gem5::EmulationPageTable::Uncacheable
@ Uncacheable
Definition: page_table.hh:99
gem5::SparcISA::FastDataAccessMMUMiss::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:677
gem5::SparcISA::MISCREG_TT
@ MISCREG_TT
Definition: misc.hh:64
gem5::SparcISA::SparcFaultBase::PrivilegeLevel
PrivilegeLevel
Definition: faults.hh:52
gem5::ThreadContext::getReg
virtual RegVal getReg(const RegId &reg) const
Definition: thread_context.cc:180
gem5::SparcISA::TrapInstruction::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:803
gem5::PCStateBase::as
Target & as()
Definition: pcstate.hh:72
gem5::ThreadContext::getMMUPtr
virtual BaseMMU * getMMUPtr()=0
gem5::ThreadContext::pcState
virtual const PCStateBase & pcState() const =0
gem5::SparcISA::PowerOnReset::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:557
gem5::replaceBits
constexpr void replaceBits(T &val, unsigned first, unsigned last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:213
gem5::SparcISA::SparcFaultBase::getNextLevel
virtual PrivilegeLevel getNextLevel(PrivilegeLevel current)=0
gem5::System::workload
Workload * workload
OS kernel.
Definition: system.hh:326
gem5::SparcISA::MachInst
uint32_t MachInst
Definition: types.hh:41
gem5::SparcISA::MaxTL
const int MaxTL
Definition: sparc_traits.hh:39
gem5::EmulationPageTable::ReadOnly
@ ReadOnly
Definition: page_table.hh:100
gem5::SparcISA::MISCREG_HPSTATE
@ MISCREG_HPSTATE
Hyper privileged registers.
Definition: misc.hh:79
gem5::SparcISA::doNormalFault
void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
This sets everything up for a normal trap except for actually jumping to the handler.
Definition: faults.cc:379
gem5::SparcISA::FastInstructionAccessMMUMiss::vaddr
Addr vaddr
Definition: faults.hh:209
gem5::SparcISA::SparcFaultBase::Privileged
@ Privileged
Definition: faults.hh:55
gem5::RefCountingPtr< StaticInst >
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
gem5::SparcProcess
Definition: process.hh:44
gem5::SparcISA::getPrivVector
void getPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, RegVal TT, RegVal TL)
Definition: faults.cc:487
gem5::SparcISA::getHyperVector
void getHyperVector(ThreadContext *tc, Addr &PC, Addr &NPC, RegVal TT)
Definition: faults.cc:479
gem5::X86ISA::H
Bitfield< 15, 8 > H
Definition: int.hh:60
bitfield.hh
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
faults.hh
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::SparcISA::SpillNNormal::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:765
gem5::SparcISA::MISCREG_TL
@ MISCREG_TL
Definition: misc.hh:68
gem5::SparcISA::int_reg::Ccr
constexpr RegId Ccr
Definition: int.hh:132
gem5::X86ISA::SH
SignedBitfield< 15, 8 > SH
Definition: int.hh:61
gem5::SparcISA::getREDVector
void getREDVector(RegVal TT, Addr &PC, Addr &NPC)
Definition: faults.cc:470
gem5::SparcISA::MISCREG_TSTATE
@ MISCREG_TSTATE
Definition: misc.hh:63
process.hh
gem5::SparcISA::TrapType
uint32_t TrapType
Definition: faults.hh:44
gem5::bits
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
compiler.hh
gem5::SparcISA::SEWorkload
Definition: se_workload.hh:48
gem5::ThreadContext::readMiscRegNoEffect
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
gem5::SparcISA::SparcFault< PowerOnReset >::trapType
TrapType trapType()
Definition: faults.hh:88
gem5::SparcISA::FastInstructionAccessMMUMiss::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:620
mmu.hh
types.hh
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::SparcISA::MaxPTL
const int MaxPTL
Definition: sparc_traits.hh:38
gem5::SparcISA::doREDFault
void doREDFault(ThreadContext *tc, TrapType tt)
This sets everything up for a RED state trap except for actually jumping to the handler.
Definition: faults.cc:303
gem5::SparcISA::red
Bitfield< 5 > red
Definition: misc.hh:124
gem5::FaultBase::invoke
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:58
full_system.hh
gem5::SparcISA::ASI_IMPLICIT
@ ASI_IMPLICIT
Definition: asi.hh:40
gem5::Process
Definition: process.hh:67
gem5::SparcISA::priv
Bitfield< 2 > priv
Definition: misc.hh:131
gem5::ThreadContext::getProcessPtr
virtual Process * getProcessPtr()=0
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
gem5::MipsISA::FaultVals
MipsFaultBase::FaultVals FaultVals
Definition: faults.cc:46
gem5::EmulationPageTable::Entry::paddr
Addr paddr
Definition: page_table.hh:58
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:214
gem5::SparcISA::NWindows
const int NWindows
Definition: sparc_traits.hh:44
gem5::SparcISA::MISCREG_HTBA
@ MISCREG_HTBA
Definition: misc.hh:82
gem5::SparcISA::MISCREG_TNPC
@ MISCREG_TNPC
Definition: misc.hh:62
gem5::SparcISA::FillNNormal::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:784
gem5::SparcISA::MISCREG_TICK
@ MISCREG_TICK
Definition: misc.hh:48
gem5::SparcISA::MISCREG_TBA
@ MISCREG_TBA
Definition: misc.hh:66
base.hh
gem5::SparcISA::asiIsReal
bool asiIsReal(ASI asi)
Definition: asi.cc:142
gem5::SparcISA::SparcFaultBase::User
@ User
Definition: faults.hh:54
gem5::SparcISA::int_reg::Cansave
constexpr RegId Cansave
Definition: int.hh:133
gem5::ThreadContext::setMiscReg
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
gem5::SparcISA::MaxGL
const int MaxGL
Definition: sparc_traits.hh:40
gem5::GenericISA::DelaySlotUPCState
Definition: pcstate.hh:530
gem5::MipsISA::tl
Bitfield< 23, 20 > tl
Definition: pra_constants.hh:254
gem5::MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
gem5::SparcISA::MISCREG_PSTATE
@ MISCREG_PSTATE
Definition: misc.hh:67
se_workload.hh
gem5::SparcISA::ASI
ASI
Definition: asi.hh:38
gem5::SparcISA::FastDataAccessMMUMiss::vaddr
Addr vaddr
Definition: faults.hh:222
gem5::SparcISA::MISCREG_TLB_DATA
@ MISCREG_TLB_DATA
Definition: misc.hh:117
trace.hh
gem5::SparcISA::SEWorkload::handleTrap
virtual void handleTrap(ThreadContext *tc, int trapNum)
Definition: se_workload.cc:56
gem5::SparcISA::MISCREG_HTSTATE
@ MISCREG_HTSTATE
Definition: misc.hh:80
gem5::SparcISA::MISCREG_CWP
@ MISCREG_CWP
Definition: misc.hh:70
gem5::SparcISA::SparcFault::vals
static FaultVals vals
Definition: faults.hh:85
gem5::ArmISA::sp
Bitfield< 0 > sp
Definition: misc_types.hh:75
gem5::SparcISA::TlbEntry::pte
PageTableEntry pte
Definition: pagetable.hh:261
gem5::SparcISA::SparcFaultBase::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition: faults.cc:497
gem5::SparcISA::MISCREG_GL
@ MISCREG_GL
Definition: misc.hh:76
gem5::SparcISA::hpriv
Bitfield< 2 > hpriv
Definition: misc.hh:123
gem5::SparcISA::MISCREG_TPC
@ MISCREG_TPC
Privilged Registers.
Definition: misc.hh:61
page_table.hh
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::EmulationPageTable::Entry
Definition: page_table.hh:56
gem5::SparcISA::enterREDState
void enterREDState(ThreadContext *tc)
This causes the thread context to enter RED state.
Definition: faults.cc:282
sparc_traits.hh
thread_context.hh
gem5::SparcISA::EnumeratedFault< TrapInstruction >::_n
uint32_t _n
Definition: faults.hh:182
gem5::SparcISA::MaxPGL
const int MaxPGL
Definition: sparc_traits.hh:41
gem5::SparcISA::TlbEntry
Definition: pagetable.hh:225
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:188
gem5::ThreadContext::setMiscRegNoEffect
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0

Generated on Sun Jul 30 2023 01:56:46 for gem5 by doxygen 1.8.17