gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
47namespace gem5
48{
49
50namespace SparcISA
51{
52
53template<> SparcFaultBase::FaultVals
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
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 */
116("fp_disabled", 0x020, 800, {{P, P, H}});
117
120("fp_exception_ieee_754", 0x021, 1110, {{P, P, H}});
121
124("fp_exception_other", 0x022, 1110, {{P, P, H}});
125
128("tag_overflow", 0x023, 1400, {{P, P, H}});
129
132("clean_window", 0x024, 1010, {{P, P, H}});
133
136("division_by_zero", 0x028, 1500, {{P, P, H}});
137
140("internal_processor_error", 0x029, 4, {{H, H, H}});
141
144("instruction_invalid_tsb_entry", 0x02A, 210, {{H, H, SH}});
145
148("data_invalid_tsb_entry", 0x02B, 1203, {{H, H, H}});
149
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
161("data_access_error", 0x032, 1210, {{H, H, H}});
162
165("data_access_protection", 0x033, 1207, {{H, H, H}});
166
169("mem_address_not_aligned", 0x034, 1020, {{H, H, H}});
170
173("LDDF_mem_address_not_aligned", 0x035, 1010, {{H, H, H}});
174
177("STDF_mem_address_not_aligned", 0x036, 1010, {{H, H, H}});
178
181("privileged_action", 0x037, 1110, {{H, H, SH}});
182
185("LDQF_mem_address_not_aligned", 0x038, 1010, {{H, H, H}});
186
189("STQF_mem_address_not_aligned", 0x039, 1010, {{H, H, H}});
190
193("instruction_real_translation_miss", 0x03E, 208, {{H, H, SH}});
194
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
206("interrupt_level_n", 0x040, 0, {{P, P, SH}});
207
210("hstick_match", 0x05E, 1601, {{H, H, H}});
211
214("trap_level_zero", 0x05F, 202, {{H, H, SH}});
215
218("interrupt_vector", 0x060, 2630, {{H, H, H}});
219
222("PA_watchpoint", 0x061, 1209, {{H, H, H}});
223
226("VA_watchpoint", 0x062, 1120, {{P, P, SH}});
227
230("fast_instruction_access_MMU_miss", 0x064, 208, {{H, H, SH}});
231
234("fast_data_access_MMU_miss", 0x068, 1203, {{H, H, H}});
235
238("fast_data_access_protection", 0x06C, 1207, {{H, H, H}});
239
242("instruction_break", 0x076, 610, {{H, H, H}});
243
246("cpu_mondo", 0x07C, 1608, {{P, P, SH}});
247
250("dev_mondo", 0x07D, 1611, {{P, P, SH}});
251
254("resume_error", 0x07E, 3330, {{P, P, SH}});
255
258("spill_n_normal", 0x080, 900, {{P, P, H}});
259
262("spill_n_other", 0x0A0, 900, {{P, P, H}});
263
266("fill_n_normal", 0x0C0, 900, {{P, P, H}});
267
270("fill_n_other", 0x0E0, 900, {{P, P, H}});
271
274("trap_instruction", 0x100, 1602, {{P, P, H}});
275
281void
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
302void
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
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
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;
350
351 hpstate.red = 1;
352 hpstate.hpriv = 1;
353 hpstate.ibe = 0;
354 hpstate.tlz = 0;
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
378void
379doNormalFault(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
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
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
446 } else { // we are going to priv
447 pstate.priv = 1;
448 pstate.cle = pstate.tle;
449 }
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
469void
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
478void
480{
482 PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
483 NPC = PC + sizeof(MachInst);
484}
485
486void
488{
490 PC = (TBA & ~mask(15)) |
491 (TL > 1 ? (1 << 14) : 0) |
492 ((TT << 5) & mask(14));
493 NPC = PC + sizeof(MachInst);
494}
495
496void
498{
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
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
556void
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;
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;
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
619void
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
676void
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.
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
764void
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
783void
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
802void
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
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:58
Target & as()
Definition pcstate.hh:73
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:677
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:620
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:784
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:557
virtual void handleTrap(ThreadContext *tc, int trapNum)
virtual PrivilegeLevel getNextLevel(PrivilegeLevel current)=0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:497
virtual TrapType trapType()=0
static FaultVals vals
Definition faults.hh:85
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:765
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:803
Workload * workload
OS kernel.
Definition system.hh:326
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual RegVal getReg(const RegId &reg) const
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
virtual System * getSystemPtr()=0
virtual const PCStateBase & pcState() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual BaseMMU * getMMUPtr()=0
virtual Process * getProcessPtr()=0
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
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:216
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#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
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 0 > sp
Definition misc_types.hh:75
Bitfield< 4 > pc
Bitfield< 23, 20 > tl
Bitfield< 0 > p
constexpr RegId Ccr
Definition int.hh:132
constexpr RegId Cansave
Definition int.hh:133
@ MISCREG_HPSTATE
Hyper privileged registers.
Definition misc.hh:79
@ MISCREG_PSTATE
Definition misc.hh:67
@ MISCREG_TLB_DATA
Definition misc.hh:117
@ MISCREG_HTSTATE
Definition misc.hh:80
@ MISCREG_TSTATE
Definition misc.hh:63
@ MISCREG_ASI
Ancillary State Registers.
Definition misc.hh:47
@ MISCREG_TPC
Privilged Registers.
Definition misc.hh:61
bool asiIsReal(ASI asi)
Definition asi.cc:142
const int NWindows
Bitfield< 5 > red
Definition misc.hh:124
Bitfield< 2 > hpriv
Definition misc.hh:123
const int MaxPGL
uint32_t TrapType
Definition faults.hh:44
void getREDVector(RegVal TT, Addr &PC, Addr &NPC)
Definition faults.cc:470
void getHyperVector(ThreadContext *tc, Addr &PC, Addr &NPC, RegVal TT)
Definition faults.cc:479
uint32_t MachInst
Definition types.hh:41
@ ASI_IMPLICIT
Definition asi.hh:40
Bitfield< 2 > priv
Definition misc.hh:131
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
const int MaxPTL
const int MaxGL
void getPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, RegVal TT, RegVal TL)
Definition faults.cc:487
void enterREDState(ThreadContext *tc)
This causes the thread context to enter RED state.
Definition faults.cc:282
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
const int MaxTL
Bitfield< 15, 8 > H
Definition int.hh:60
SignedBitfield< 15, 8 > SH
Definition int.hh:61
Bitfield< 20 > level
Definition intmessage.hh:51
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t RegVal
Definition types.hh:173
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
Declarations of a non-full system Page Table.

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0