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

Generated on Tue Mar 23 2021 19:41:19 for gem5 by doxygen 1.8.17