gem5  v19.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  * Authors: Gabe Black
29  * Kevin Lim
30  */
31 
32 #include "arch/sparc/faults.hh"
33 
34 #include <algorithm>
35 
36 #include "arch/sparc/isa_traits.hh"
37 #include "arch/sparc/process.hh"
38 #include "arch/sparc/tlb.hh"
39 #include "arch/sparc/types.hh"
40 #include "base/bitfield.hh"
41 #include "base/trace.hh"
42 #include "cpu/base.hh"
43 #include "cpu/thread_context.hh"
44 #include "mem/page_table.hh"
45 #include "sim/full_system.hh"
46 #include "sim/process.hh"
47 
48 using namespace std;
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 {
307  PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
308  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
309  RegVal CCR = tc->readIntReg(NumIntArchRegs + 2);
312  RegVal CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
314  PCState pc = tc->pcState();
315 
316  TL++;
317 
318  Addr pcMask = pstate.am ? mask(32) : mask(64);
319 
320  // set TSTATE.gl to gl
321  replaceBits(TSTATE, 42, 40, GL);
322  // set TSTATE.ccr to ccr
323  replaceBits(TSTATE, 39, 32, CCR);
324  // set TSTATE.asi to asi
325  replaceBits(TSTATE, 31, 24, ASI);
326  // set TSTATE.pstate to pstate
327  replaceBits(TSTATE, 20, 8, pstate);
328  // set TSTATE.cwp to cwp
329  replaceBits(TSTATE, 4, 0, CWP);
330 
331  // Write back TSTATE
332  tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
333 
334  // set TPC to PC
335  tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
336  // set TNPC to NPC
337  tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
338 
339  // set HTSTATE.hpstate to hpstate
340  tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
341 
342  // TT = trap type;
344 
345  // Update GL
346  tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
347 
348  bool priv = pstate.priv; // just save the priv bit
349  pstate = 0;
350  pstate.priv = priv;
351  pstate.pef = 1;
352  tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
353 
354  hpstate.red = 1;
355  hpstate.hpriv = 1;
356  hpstate.ibe = 0;
357  hpstate.tlz = 0;
358  tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
359 
360  bool changedCWP = true;
361  if (tt == 0x24)
362  CWP++;
363  else if (0x80 <= tt && tt <= 0xbf)
364  CWP += (CANSAVE + 2);
365  else if (0xc0 <= tt && tt <= 0xff)
366  CWP--;
367  else
368  changedCWP = false;
369 
370  if (changedCWP) {
371  CWP = (CWP + NWindows) % NWindows;
372  tc->setMiscReg(MISCREG_CWP, CWP);
373  }
374 }
375 
381 void
382 doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
383 {
386  PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
387  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
388  RegVal CCR = tc->readIntReg(NumIntArchRegs + 2);
391  RegVal CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
393  PCState pc = tc->pcState();
394 
395  // Increment the trap level
396  TL++;
398 
399  Addr pcMask = pstate.am ? mask(32) : mask(64);
400 
401  // Save off state
402 
403  // set TSTATE.gl to gl
404  replaceBits(TSTATE, 42, 40, GL);
405  // set TSTATE.ccr to ccr
406  replaceBits(TSTATE, 39, 32, CCR);
407  // set TSTATE.asi to asi
408  replaceBits(TSTATE, 31, 24, ASI);
409  // set TSTATE.pstate to pstate
410  replaceBits(TSTATE, 20, 8, pstate);
411  // set TSTATE.cwp to cwp
412  replaceBits(TSTATE, 4, 0, CWP);
413 
414  // Write back TSTATE
415  tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
416 
417  // set TPC to PC
418  tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
419  // set TNPC to NPC
420  tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
421 
422  // set HTSTATE.hpstate to hpstate
423  tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
424 
425  // TT = trap type;
427 
428  // Update the global register level
429  if (!gotoHpriv)
430  tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxPGL));
431  else
432  tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL));
433 
434  // pstate.mm is unchanged
435  pstate.pef = 1; // PSTATE.pef = whether or not an fpu is present
436  pstate.am = 0;
437  pstate.ie = 0;
438  // pstate.tle is unchanged
439  // pstate.tct = 0
440 
441  if (gotoHpriv) {
442  pstate.cle = 0;
443  // The manual says PSTATE.priv should be 0, but Legion leaves it alone
444  hpstate.red = 0;
445  hpstate.hpriv = 1;
446  hpstate.ibe = 0;
447  // hpstate.tlz is unchanged
448  tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
449  } else { // we are going to priv
450  pstate.priv = 1;
451  pstate.cle = pstate.tle;
452  }
453  tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
454 
455 
456  bool changedCWP = true;
457  if (tt == 0x24)
458  CWP++;
459  else if (0x80 <= tt && tt <= 0xbf)
460  CWP += (CANSAVE + 2);
461  else if (0xc0 <= tt && tt <= 0xff)
462  CWP--;
463  else
464  changedCWP = false;
465 
466  if (changedCWP) {
467  CWP = (CWP + NWindows) % NWindows;
468  tc->setMiscReg(MISCREG_CWP, CWP);
469  }
470 }
471 
472 void
473 getREDVector(RegVal TT, Addr &PC, Addr &NPC)
474 {
475  //XXX The following constant might belong in a header file.
476  const Addr RSTVAddr = 0xFFF0000000ULL;
477  PC = RSTVAddr | ((TT << 5) & 0xFF);
478  NPC = PC + sizeof(MachInst);
479 }
480 
481 void
483 {
485  PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
486  NPC = PC + sizeof(MachInst);
487 }
488 
489 void
491 {
493  PC = (TBA & ~mask(15)) |
494  (TL > 1 ? (1 << 14) : 0) |
495  ((TT << 5) & mask(14));
496  NPC = PC + sizeof(MachInst);
497 }
498 
499 void
500 SparcFaultBase::invoke(ThreadContext * tc, const StaticInstPtr &inst)
501 {
502  FaultBase::invoke(tc);
503  if (!FullSystem)
504  return;
505 
506  countStat()++;
507 
508  // We can refer to this to see what the trap level -was-, but something
509  // in the middle could change it in the regfile out from under us.
512  PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
513  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
514 
515  Addr PC, NPC;
516 
517  PrivilegeLevel current;
518  if (hpstate.hpriv)
519  current = Hyperprivileged;
520  else if (pstate.priv)
521  current = Privileged;
522  else
523  current = User;
524 
525  PrivilegeLevel level = getNextLevel(current);
526 
527  if (hpstate.red || (tl == MaxTL - 1)) {
528  getREDVector(5, PC, NPC);
529  doREDFault(tc, tt);
530  // This changes the hpstate and pstate, so we need to make sure we
531  // save the old version on the trap stack in doREDFault.
532  enterREDState(tc);
533  } else if (tl == MaxTL) {
534  panic("Should go to error state here.. crap\n");
535  // Do error_state somehow?
536  // Probably inject a WDR fault using the interrupt mechanism.
537  // What should the PC and NPC be set to?
538  } else if (tl > MaxPTL && level == Privileged) {
539  // guest_watchdog fault
540  doNormalFault(tc, trapType(), true);
541  getHyperVector(tc, PC, NPC, 2);
542  } else if (level == Hyperprivileged ||
543  (level == Privileged && trapType() >= 384)) {
544  doNormalFault(tc, trapType(), true);
545  getHyperVector(tc, PC, NPC, trapType());
546  } else {
547  doNormalFault(tc, trapType(), false);
548  getPrivVector(tc, PC, NPC, trapType(), tl + 1);
549  }
550 
551  PCState pc;
552  pc.pc(PC);
553  pc.npc(NPC);
554  pc.nnpc(NPC + sizeof(MachInst));
555  pc.upc(0);
556  pc.nupc(1);
557  tc->pcState(pc);
558 }
559 
560 void
561 PowerOnReset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
562 {
563  // For SPARC, when a system is first started, there is a power
564  // on reset Trap which sets the processor into the following state.
565  // Bits that aren't set aren't defined on startup.
566 
568  tc->setMiscRegNoEffect(MISCREG_TT, trapType());
570 
571  PSTATE pstate = 0;
572  pstate.pef = 1;
573  pstate.priv = 1;
574  tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
575 
576  // Turn on red and hpriv, set everything else to 0
577  HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
578  hpstate.red = 1;
579  hpstate.hpriv = 1;
580  hpstate.ibe = 0;
581  hpstate.tlz = 0;
582  tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
583 
584  // The tick register is unreadable by nonprivileged software
585  tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
586 
587  // Enter RED state. We do this last so that the actual state preserved in
588  // the trap stack is the state from before this fault.
589  enterREDState(tc);
590 
591  Addr PC, NPC;
592  getREDVector(trapType(), PC, NPC);
593 
594  PCState pc;
595  pc.pc(PC);
596  pc.npc(NPC);
597  pc.nnpc(NPC + sizeof(MachInst));
598  pc.upc(0);
599  pc.nupc(1);
600  tc->pcState(pc);
601 
602  // These registers are specified as "undefined" after a POR, and they
603  // should have reasonable values after the miscregfile is reset
604  /*
605  // Clear all the soft interrupt bits
606  softint = 0;
607  // disable timer compare interrupts, reset tick_cmpr
608  tc->setMiscRegNoEffect(MISCREG_
609  tick_cmprFields.int_dis = 1;
610  tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
611  stickFields.npt = 1; // The TICK register is unreadable by by !priv
612  stick_cmprFields.int_dis = 1; // disable timer compare interrupts
613  stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
614 
615  tt[tl] = _trapType;
616 
617  hintp = 0; // no interrupts pending
618  hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
619  hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
620  */
621 }
622 
623 void
624 FastInstructionAccessMMUMiss::invoke(ThreadContext *tc,
625  const StaticInstPtr &inst)
626 {
627  if (FullSystem) {
628  SparcFaultBase::invoke(tc, inst);
629  return;
630  }
631 
632  Process *p = tc->getProcessPtr();
633  const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
634  panic_if(!pte, "Tried to execute unmapped address %#x.\n", vaddr);
635 
636  Addr alignedvaddr = p->pTable->pageAlign(vaddr);
637 
638  // Grab fields used during instruction translation to figure out
639  // which context to use.
640  uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
641 
642  // Inside a VM, a real address is the address that guest OS would
643  // interpret to be a physical address. To map to the physical address,
644  // it still needs to undergo a translation. The instruction
645  // translation code in the SPARC ITLB code assumes that the context is
646  // zero (kernel-level) if real addressing is being used.
647  bool is_real_address = !bits(tlbdata, 4);
648 
649  // The SPARC ITLB code assumes that traps are executed in context
650  // zero so we carry that assumption through here.
651  bool trapped = bits(tlbdata, 18, 16) > 0;
652 
653  // The primary context acts as a PASID. It allows the MMU to
654  // distinguish between virtual addresses that would alias to the
655  // same physical address (if two or more processes shared the same
656  // virtual address mapping).
657  int primary_context = bits(tlbdata, 47, 32);
658 
659  // The partition id distinguishes between virtualized environments.
660  int const partition_id = 0;
661 
662  // Given the assumptions in the translateInst code in the SPARC ITLB,
663  // the logic works out to the following for the context.
664  int context_id = (is_real_address || trapped) ? 0 : primary_context;
665 
666  TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr,
669 
670  // Insert the TLB entry.
671  // The entry specifying whether the address is "real" is set to
672  // false for syscall emulation mode regardless of whether the
673  // address is real in preceding code. Not sure sure that this is
674  // correct, but also not sure if it matters at all.
675  dynamic_cast<TLB *>(tc->getITBPtr())->
676  insert(alignedvaddr, partition_id, context_id, false, entry.pte);
677 }
678 
679 void
680 FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst)
681 {
682  if (FullSystem) {
683  SparcFaultBase::invoke(tc, inst);
684  return;
685  }
686 
687  Process *p = tc->getProcessPtr();
688  const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
689  if (!pte && p->fixupStackFault(vaddr))
690  pte = p->pTable->lookup(vaddr);
691  panic_if(!pte, "Tried to access unmapped address %#x.\n", vaddr);
692 
693  Addr alignedvaddr = p->pTable->pageAlign(vaddr);
694 
695  // Grab fields used during data translation to figure out
696  // which context to use.
697  uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
698 
699  // The primary context acts as a PASID. It allows the MMU to
700  // distinguish between virtual addresses that would alias to the
701  // same physical address (if two or more processes shared the same
702  // virtual address mapping). There's a secondary context used in the
703  // DTLB translation code, but it should __probably__ be zero for
704  // syscall emulation code. (The secondary context is used by Solaris
705  // to allow kernel privilege code to access user space code:
706  // [ISBN 0-13-022496-0]:PG199.)
707  int primary_context = bits(tlbdata, 47, 32);
708 
709  // "Hyper-Privileged Mode" is in use. There are three main modes of
710  // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
711  // User Mode.
712  int hpriv = bits(tlbdata, 0);
713 
714  // Reset, Error and Debug state is in use. Something horrible has
715  // happened or the system is operating in Reset Mode.
716  int red = bits(tlbdata, 1);
717 
718  // Inside a VM, a real address is the address that guest OS would
719  // interpret to be a physical address. To map to the physical address,
720  // it still needs to undergo a translation. The instruction
721  // translation code in the SPARC ITLB code assumes that the context is
722  // zero (kernel-level) if real addressing is being used.
723  int is_real_address = !bits(tlbdata, 5);
724 
725  // Grab the address space identifier register from the thread context.
726  // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
727  // MISCREG_ASI causes me to think that the ASI register implementation
728  // might be bugged. The NoEffect variant changes the ASI register
729  // value in the architectural state while the normal variant changes
730  // the context field in the thread context's currently decoded request
731  // but does not directly affect the ASI register value in the
732  // architectural state. The ASI values and the context field in the
733  // request packet seem to have completely different uses.
734  RegVal reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
735  ASI asi = static_cast<ASI>(reg_asi);
736 
737  // The SPARC DTLB code assumes that traps are executed in context
738  // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
739  // an assumption that the nucleus address space is being used, but
740  // the context is the relevant issue since we need to pass it to TLB.
741  bool trapped = bits(tlbdata, 18, 16) > 0;
742 
743  // Given the assumptions in the translateData code in the SPARC DTLB,
744  // the logic works out to the following for the context.
745  int context_id = ((!hpriv && !red && is_real_address) ||
746  asiIsReal(asi) ||
747  (trapped && asi == ASI_IMPLICIT))
748  ? 0 : primary_context;
749 
750  // The partition id distinguishes between virtualized environments.
751  int const partition_id = 0;
752 
753  TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr,
756 
757  // Insert the TLB entry.
758  // The entry specifying whether the address is "real" is set to
759  // false for syscall emulation mode regardless of whether the
760  // address is real in preceding code. Not sure sure that this is
761  // correct, but also not sure if it matters at all.
762  dynamic_cast<TLB *>(tc->getDTBPtr())->
763  insert(alignedvaddr, partition_id, context_id, false, entry.pte);
764 }
765 
766 void
767 SpillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst)
768 {
769  if (FullSystem) {
770  SparcFaultBase::invoke(tc, inst);
771  return;
772  }
773 
774  doNormalFault(tc, trapType(), false);
775 
776  Process *p = tc->getProcessPtr();
777 
778  SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
779  assert(sp);
780 
781  // Then adjust the PC and NPC
782  tc->pcState(sp->readSpillStart());
783 }
784 
785 void
786 FillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst)
787 {
788  if (FullSystem) {
789  SparcFaultBase::invoke(tc, inst);
790  return;
791  }
792 
793  doNormalFault(tc, trapType(), false);
794 
795  Process *p = tc->getProcessPtr();
796 
797  SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
798  assert(sp);
799 
800  // Then adjust the PC and NPC
801  tc->pcState(sp->readFillStart());
802 }
803 
804 void
805 TrapInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst)
806 {
807  if (FullSystem) {
808  SparcFaultBase::invoke(tc, inst);
809  return;
810  }
811 
812  // In SE, this mechanism is how the process requests a service from
813  // the operating system. We'll get the process object from the thread
814  // context and let it service the request.
815 
816  Process *p = tc->getProcessPtr();
817 
818  SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
819  assert(sp);
820 
821  Fault fault;
822  sp->handleTrap(_n, tc, &fault);
823 
824  // We need to explicitly advance the pc, since that's not done for us
825  // on a faulting instruction
826  PCState pc = tc->pcState();
827  pc.advance();
828  tc->pcState(pc);
829 }
830 
831 } // namespace SparcISA
832 
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
bool asiIsReal(ASI asi)
Definition: asi.cc:142
void getREDVector(RegVal TT, Addr &PC, Addr &NPC)
Definition: faults.cc:473
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual BaseTLB * getDTBPtr()=0
virtual TheISA::PCState pcState() const =0
virtual RegVal readIntReg(RegIndex reg_idx) const =0
uint32_t MachInst
Definition: types.hh:40
uint32_t TrapType
Definition: faults.hh:43
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
const int MaxGL
Definition: sparc_traits.hh:39
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:382
void getHyperVector(ThreadContext *tc, Addr &PC, Addr &NPC, RegVal TT)
Definition: faults.cc:482
Bitfield< 0 > sp
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:136
Bitfield< 15, 8 > H
Definition: int.hh:57
virtual Process * getProcessPtr()=0
uint64_t RegVal
Definition: types.hh:168
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
ThreadContext is the external interface to all thread state for anything outside of the CPU...
uint32_t MachInst
Definition: types.hh:40
Bitfield< 2 > hpriv
Definition: miscregs.hh:121
MicroPC upc() const
Definition: types.hh:383
Bitfield< 23, 20 > tl
Addr pageAlign(Addr a)
Definition: page_table.hh:107
Bitfield< 4 > pc
Hyper privileged registers.
Definition: miscregs.hh:77
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:157
SparcFaultBase::FaultVals vals
Definition: faults.hh:291
MicroPC nupc() const
Definition: types.hh:386
virtual BaseTLB * getITBPtr()=0
Addr readSpillStart()
Definition: process.hh:68
void enterREDState(ThreadContext *tc)
This causes the thread context to enter RED state.
Definition: faults.cc:282
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
#define ULL(N)
uint64_t constant
Definition: types.hh:50
Addr npc() const
Definition: types.hh:151
Ancillary State Registers.
Definition: miscregs.hh:45
const int MaxPGL
Definition: sparc_traits.hh:40
Bitfield< 20 > level
Definition: intmessage.hh:49
SignedBitfield< 15, 8 > SH
Definition: int.hh:58
bool fixupStackFault(Addr vaddr)
Attempt to fix up a fault at vaddr by allocating a page on the stack.
Definition: process.cc:362
const int NumIntArchRegs
Definition: registers.hh:89
EmulationPageTable * pTable
Definition: process.hh:181
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
Declarations of a non-full system Page Table.
const int MaxTL
Definition: sparc_traits.hh:38
Definition: asi.cc:34
Privilged Registers.
Definition: miscregs.hh:59
MipsFaultBase::FaultVals FaultVals
Definition: faults.cc:49
virtual void handleTrap(int trapNum, ThreadContext *tc, Fault *fault)
Definition: process.cc:71
const int NWindows
Definition: sparc_traits.hh:43
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
Bitfield< 5 > red
Definition: miscregs.hh:122
const Entry * lookup(Addr vaddr)
Lookup function.
Definition: page_table.cc:134
Bitfield< 2 > priv
Definition: miscregs.hh:129
const int MaxPTL
Definition: sparc_traits.hh:37
Bitfield< 3, 0 > mask
Definition: types.hh:64
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
void getPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, RegVal TT, RegVal TL)
Definition: faults.cc:490
Bitfield< 0 > p
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
uint64_t pid() const
Definition: page_table.hh:83
ASI
Definition: asi.hh:38
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr)
Definition: faults.cc:43
Addr readFillStart()
Definition: process.hh:67

Generated on Fri Feb 28 2020 16:26:55 for gem5 by doxygen 1.8.13