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

Generated on Mon Oct 27 2025 04:12:55 for gem5 by doxygen 1.14.0