faults.cc revision 3576
12221SN/A/*
22221SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32221SN/A * All rights reserved.
42221SN/A *
52221SN/A * Redistribution and use in source and binary forms, with or without
62221SN/A * modification, are permitted provided that the following conditions are
72221SN/A * met: redistributions of source code must retain the above copyright
82221SN/A * notice, this list of conditions and the following disclaimer;
92221SN/A * redistributions in binary form must reproduce the above copyright
102221SN/A * notice, this list of conditions and the following disclaimer in the
112221SN/A * documentation and/or other materials provided with the distribution;
122221SN/A * neither the name of the copyright holders nor the names of its
132221SN/A * contributors may be used to endorse or promote products derived from
142221SN/A * this software without specific prior written permission.
152221SN/A *
162221SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172221SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182221SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192221SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202221SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212221SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222221SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232221SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242221SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252221SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262221SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Gabe Black
292665Ssaidi@eecs.umich.edu *          Kevin Lim
302221SN/A */
312221SN/A
323415Sgblack@eecs.umich.edu#include <algorithm>
333415Sgblack@eecs.umich.edu
342223SN/A#include "arch/sparc/faults.hh"
353415Sgblack@eecs.umich.edu#include "arch/sparc/isa_traits.hh"
363415Sgblack@eecs.umich.edu#include "base/bitfield.hh"
373415Sgblack@eecs.umich.edu#include "base/trace.hh"
383523Sgblack@eecs.umich.edu#include "config/full_system.hh"
393415Sgblack@eecs.umich.edu#include "cpu/base.hh"
402680Sktlim@umich.edu#include "cpu/thread_context.hh"
412800Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
423523Sgblack@eecs.umich.edu#include "arch/sparc/process.hh"
433415Sgblack@eecs.umich.edu#include "mem/page_table.hh"
442800Ssaidi@eecs.umich.edu#include "sim/process.hh"
452800Ssaidi@eecs.umich.edu#endif
462221SN/A
473415Sgblack@eecs.umich.eduusing namespace std;
483415Sgblack@eecs.umich.edu
492223SN/Anamespace SparcISA
502221SN/A{
512221SN/A
523573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
533576Sgblack@eecs.umich.edu    SparcFault<PowerOnReset>::vals =
543576Sgblack@eecs.umich.edu    {"power_on_reset", 0x001, 0, {H, H, H}};
552221SN/A
563573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
573576Sgblack@eecs.umich.edu    SparcFault<WatchDogReset>::vals =
583576Sgblack@eecs.umich.edu    {"watch_dog_reset", 0x002, 120, {H, H, H}};
592221SN/A
603573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
613576Sgblack@eecs.umich.edu    SparcFault<ExternallyInitiatedReset>::vals =
623576Sgblack@eecs.umich.edu    {"externally_initiated_reset", 0x003, 110, {H, H, H}};
632221SN/A
643573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
653576Sgblack@eecs.umich.edu    SparcFault<SoftwareInitiatedReset>::vals =
663576Sgblack@eecs.umich.edu    {"software_initiated_reset", 0x004, 130, {SH, SH, H}};
672221SN/A
683573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
693576Sgblack@eecs.umich.edu    SparcFault<REDStateException>::vals =
703576Sgblack@eecs.umich.edu    {"RED_state_exception", 0x005, 1, {H, H, H}};
712221SN/A
723573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
733576Sgblack@eecs.umich.edu    SparcFault<StoreError>::vals =
743576Sgblack@eecs.umich.edu    {"store_error", 0x007, 201, {H, H, H}};
752221SN/A
763573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
773576Sgblack@eecs.umich.edu    SparcFault<InstructionAccessException>::vals =
783576Sgblack@eecs.umich.edu    {"instruction_access_exception", 0x008, 300, {H, H, H}};
793576Sgblack@eecs.umich.edu
803576Sgblack@eecs.umich.edu//XXX This trap is apparently dropped from ua2005
813576Sgblack@eecs.umich.edu/*template<> SparcFaultBase::FaultVals
823576Sgblack@eecs.umich.edu    SparcFault<InstructionAccessMMUMiss>::vals =
833576Sgblack@eecs.umich.edu    {"inst_mmu", 0x009, 2, {H, H, H}};*/
842221SN/A
853573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
863576Sgblack@eecs.umich.edu    SparcFault<InstructionAccessError>::vals =
873576Sgblack@eecs.umich.edu    {"instruction_access_error", 0x00A, 400, {H, H, H}};
882221SN/A
893573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
903576Sgblack@eecs.umich.edu    SparcFault<IllegalInstruction>::vals =
913576Sgblack@eecs.umich.edu    {"illegal_instruction", 0x010, 620, {H, H, H}};
922221SN/A
933573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
943576Sgblack@eecs.umich.edu    SparcFault<PrivilegedOpcode>::vals =
953576Sgblack@eecs.umich.edu    {"privileged_opcode", 0x011, 700, {P, SH, SH}};
963576Sgblack@eecs.umich.edu
973576Sgblack@eecs.umich.edu//XXX This trap is apparently dropped from ua2005
983576Sgblack@eecs.umich.edu/*template<> SparcFaultBase::FaultVals
993576Sgblack@eecs.umich.edu    SparcFault<UnimplementedLDD>::vals =
1003576Sgblack@eecs.umich.edu    {"unimp_ldd", 0x012, 6, {H, H, H}};*/
1013576Sgblack@eecs.umich.edu
1023576Sgblack@eecs.umich.edu//XXX This trap is apparently dropped from ua2005
1033576Sgblack@eecs.umich.edu/*template<> SparcFaultBase::FaultVals
1043576Sgblack@eecs.umich.edu    SparcFault<UnimplementedSTD>::vals =
1053576Sgblack@eecs.umich.edu    {"unimp_std", 0x013, 6, {H, H, H}};*/
1062221SN/A
1073573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1083576Sgblack@eecs.umich.edu    SparcFault<FpDisabled>::vals =
1093576Sgblack@eecs.umich.edu    {"fp_disabled", 0x020, 800, {P, P, H}};
1102221SN/A
1113573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1123576Sgblack@eecs.umich.edu    SparcFault<FpExceptionIEEE754>::vals =
1133576Sgblack@eecs.umich.edu    {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}};
1142221SN/A
1153573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1163576Sgblack@eecs.umich.edu    SparcFault<FpExceptionOther>::vals =
1173576Sgblack@eecs.umich.edu    {"fp_exception_other", 0x022, 1110, {P, P, H}};
1182221SN/A
1193573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1203576Sgblack@eecs.umich.edu    SparcFault<TagOverflow>::vals =
1213576Sgblack@eecs.umich.edu    {"tag_overflow", 0x023, 1400, {P, P, H}};
1222221SN/A
1233573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1243576Sgblack@eecs.umich.edu    SparcFault<CleanWindow>::vals =
1253576Sgblack@eecs.umich.edu    {"clean_window", 0x024, 1010, {P, P, H}};
1262221SN/A
1273573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1283576Sgblack@eecs.umich.edu    SparcFault<DivisionByZero>::vals =
1293576Sgblack@eecs.umich.edu    {"division_by_zero", 0x028, 1500, {P, P, H}};
1302223SN/A
1313573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1323576Sgblack@eecs.umich.edu    SparcFault<InternalProcessorError>::vals =
1333576Sgblack@eecs.umich.edu    {"internal_processor_error", 0x029, 4, {H, H, H}};
1342223SN/A
1353573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1363576Sgblack@eecs.umich.edu    SparcFault<InstructionInvalidTSBEntry>::vals =
1373576Sgblack@eecs.umich.edu    {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}};
1382223SN/A
1393573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1403576Sgblack@eecs.umich.edu    SparcFault<DataInvalidTSBEntry>::vals =
1413576Sgblack@eecs.umich.edu    {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}};
1422223SN/A
1433573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1443576Sgblack@eecs.umich.edu    SparcFault<DataAccessException>::vals =
1453576Sgblack@eecs.umich.edu    {"data_access_exception", 0x030, 1201, {H, H, H}};
1463576Sgblack@eecs.umich.edu
1473576Sgblack@eecs.umich.edu//XXX This trap is apparently dropped from ua2005
1483576Sgblack@eecs.umich.edu/*template<> SparcFaultBase::FaultVals
1493576Sgblack@eecs.umich.edu    SparcFault<DataAccessMMUMiss>::vals =
1503576Sgblack@eecs.umich.edu    {"data_mmu", 0x031, 12, {H, H, H}};*/
1512223SN/A
1523573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1533576Sgblack@eecs.umich.edu    SparcFault<DataAccessError>::vals =
1543576Sgblack@eecs.umich.edu    {"data_access_error", 0x032, 1210, {H, H, H}};
1552223SN/A
1563573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1573576Sgblack@eecs.umich.edu    SparcFault<DataAccessProtection>::vals =
1583576Sgblack@eecs.umich.edu    {"data_access_protection", 0x033, 1207, {H, H, H}};
1592223SN/A
1603573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1613576Sgblack@eecs.umich.edu    SparcFault<MemAddressNotAligned>::vals =
1623576Sgblack@eecs.umich.edu    {"mem_address_not_aligned", 0x034, 1020, {H, H, H}};
1632223SN/A
1643573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1653576Sgblack@eecs.umich.edu    SparcFault<LDDFMemAddressNotAligned>::vals =
1663576Sgblack@eecs.umich.edu    {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}};
1672223SN/A
1683573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1693576Sgblack@eecs.umich.edu    SparcFault<STDFMemAddressNotAligned>::vals =
1703576Sgblack@eecs.umich.edu    {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}};
1712223SN/A
1723573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1733576Sgblack@eecs.umich.edu    SparcFault<PrivilegedAction>::vals =
1743576Sgblack@eecs.umich.edu    {"privileged_action", 0x037, 1110, {H, H, SH}};
1752223SN/A
1763573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1773576Sgblack@eecs.umich.edu    SparcFault<LDQFMemAddressNotAligned>::vals =
1783576Sgblack@eecs.umich.edu    {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}};
1792223SN/A
1803573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1813576Sgblack@eecs.umich.edu    SparcFault<STQFMemAddressNotAligned>::vals =
1823576Sgblack@eecs.umich.edu    {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}};
1832223SN/A
1843573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1853576Sgblack@eecs.umich.edu    SparcFault<InstructionRealTranslationMiss>::vals =
1863576Sgblack@eecs.umich.edu    {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}};
1872223SN/A
1883573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1893576Sgblack@eecs.umich.edu    SparcFault<DataRealTranslationMiss>::vals =
1903576Sgblack@eecs.umich.edu    {"data_real_translation_miss", 0x03F, 1203, {H, H, H}};
1912223SN/A
1923576Sgblack@eecs.umich.edu//XXX This trap is apparently dropped from ua2005
1933576Sgblack@eecs.umich.edu/*template<> SparcFaultBase::FaultVals
1943576Sgblack@eecs.umich.edu    SparcFault<AsyncDataError>::vals =
1953576Sgblack@eecs.umich.edu    {"async_data", 0x040, 2, {H, H, H}};*/
1962527SN/A
1973573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
1983576Sgblack@eecs.umich.edu    SparcFault<InterruptLevelN>::vals =
1993576Sgblack@eecs.umich.edu    {"interrupt_level_n", 0x041, 0, {P, P, SH}};
2002223SN/A
2013573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2023576Sgblack@eecs.umich.edu    SparcFault<HstickMatch>::vals =
2033576Sgblack@eecs.umich.edu    {"hstick_match", 0x05E, 1601, {H, H, H}};
2042223SN/A
2053573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2063576Sgblack@eecs.umich.edu    SparcFault<TrapLevelZero>::vals =
2073576Sgblack@eecs.umich.edu    {"trap_level_zero", 0x05F, 202, {H, H, SH}};
2082223SN/A
2093573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2103576Sgblack@eecs.umich.edu    SparcFault<PAWatchpoint>::vals =
2113576Sgblack@eecs.umich.edu    {"PA_watchpoint", 0x061, 1209, {H, H, H}};
2122223SN/A
2133573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2143576Sgblack@eecs.umich.edu    SparcFault<VAWatchpoint>::vals =
2153576Sgblack@eecs.umich.edu    {"VA_watchpoint", 0x062, 1120, {P, P, SH}};
2162223SN/A
2173573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2183576Sgblack@eecs.umich.edu    SparcFault<FastInstructionAccessMMUMiss>::vals =
2193576Sgblack@eecs.umich.edu    {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}};
2203576Sgblack@eecs.umich.edu
2213576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2223576Sgblack@eecs.umich.edu    SparcFault<FastDataAccessMMUMiss>::vals =
2233576Sgblack@eecs.umich.edu    {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}};
2243576Sgblack@eecs.umich.edu
2253576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2263576Sgblack@eecs.umich.edu    SparcFault<FastDataAccessProtection>::vals =
2273576Sgblack@eecs.umich.edu    {"fast_data_access_protection", 0x06C, 1207, {H, H, H}};
2283576Sgblack@eecs.umich.edu
2293576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2303576Sgblack@eecs.umich.edu    SparcFault<InstructionBreakpoint>::vals =
2313576Sgblack@eecs.umich.edu    {"instruction_break", 0x076, 610, {H, H, H}};
2323576Sgblack@eecs.umich.edu
2333576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2343576Sgblack@eecs.umich.edu    SparcFault<CpuMondo>::vals =
2353576Sgblack@eecs.umich.edu    {"cpu_mondo", 0x07C, 1608, {P, P, SH}};
2363576Sgblack@eecs.umich.edu
2373576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2383576Sgblack@eecs.umich.edu    SparcFault<DevMondo>::vals =
2393576Sgblack@eecs.umich.edu    {"dev_mondo", 0x07D, 1611, {P, P, SH}};
2403576Sgblack@eecs.umich.edu
2413576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2423576Sgblack@eecs.umich.edu    SparcFault<ResumeableError>::vals =
2433576Sgblack@eecs.umich.edu    {"resume_error", 0x07E, 3330, {P, P, SH}};
2443576Sgblack@eecs.umich.edu
2453576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2463576Sgblack@eecs.umich.edu    SparcFault<SpillNNormal>::vals =
2473576Sgblack@eecs.umich.edu    {"spill_n_normal", 0x080, 900, {P, P, H}};
2483576Sgblack@eecs.umich.edu
2493576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2503576Sgblack@eecs.umich.edu    SparcFault<SpillNOther>::vals =
2513576Sgblack@eecs.umich.edu    {"spill_n_other", 0x0A0, 900, {P, P, H}};
2523576Sgblack@eecs.umich.edu
2533576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2543576Sgblack@eecs.umich.edu    SparcFault<FillNNormal>::vals =
2553576Sgblack@eecs.umich.edu    {"fill_n_normal", 0x0C0, 900, {P, P, H}};
2563576Sgblack@eecs.umich.edu
2573576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2583576Sgblack@eecs.umich.edu    SparcFault<FillNOther>::vals =
2593576Sgblack@eecs.umich.edu    {"fill_n_other", 0x0E0, 900, {P, P, H}};
2603576Sgblack@eecs.umich.edu
2613576Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2623576Sgblack@eecs.umich.edu    SparcFault<TrapInstruction>::vals =
2633576Sgblack@eecs.umich.edu    {"trap_instruction", 0x100, 1602, {P, P, H}};
2642223SN/A
2652800Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
2663573Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2673576Sgblack@eecs.umich.edu    SparcFault<PageTableFault>::vals =
2683576Sgblack@eecs.umich.edu    {"page_table_fault", 0x0000, 0, {SH, SH, SH}};
2692800Ssaidi@eecs.umich.edu#endif
2702800Ssaidi@eecs.umich.edu
2713415Sgblack@eecs.umich.edu/**
2723415Sgblack@eecs.umich.edu * This sets everything up for a normal trap except for actually jumping to
2733415Sgblack@eecs.umich.edu * the handler. It will need to be expanded to include the state machine in
2743415Sgblack@eecs.umich.edu * the manual. Right now it assumes that traps will always be to the
2753415Sgblack@eecs.umich.edu * privileged level.
2763415Sgblack@eecs.umich.edu */
2773415Sgblack@eecs.umich.edu
2783415Sgblack@eecs.umich.eduvoid doNormalFault(ThreadContext *tc, TrapType tt)
2793415Sgblack@eecs.umich.edu{
2803415Sgblack@eecs.umich.edu    uint64_t TL = tc->readMiscReg(MISCREG_TL);
2813415Sgblack@eecs.umich.edu    uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE);
2823415Sgblack@eecs.umich.edu    uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE);
2833415Sgblack@eecs.umich.edu    uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
2843415Sgblack@eecs.umich.edu    uint64_t CCR = tc->readMiscReg(MISCREG_CCR);
2853415Sgblack@eecs.umich.edu    uint64_t ASI = tc->readMiscReg(MISCREG_ASI);
2863415Sgblack@eecs.umich.edu    uint64_t CWP = tc->readMiscReg(MISCREG_CWP);
2873415Sgblack@eecs.umich.edu    uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
2883415Sgblack@eecs.umich.edu    uint64_t GL = tc->readMiscReg(MISCREG_GL);
2893415Sgblack@eecs.umich.edu    uint64_t PC = tc->readPC();
2903415Sgblack@eecs.umich.edu    uint64_t NPC = tc->readNextPC();
2913415Sgblack@eecs.umich.edu
2923415Sgblack@eecs.umich.edu    //Increment the trap level
2933415Sgblack@eecs.umich.edu    TL++;
2943415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TL, TL);
2953415Sgblack@eecs.umich.edu
2963415Sgblack@eecs.umich.edu    //Save off state
2973415Sgblack@eecs.umich.edu
2983415Sgblack@eecs.umich.edu    //set TSTATE.gl to gl
2993415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 42, 40, GL);
3003415Sgblack@eecs.umich.edu    //set TSTATE.ccr to ccr
3013415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 39, 32, CCR);
3023415Sgblack@eecs.umich.edu    //set TSTATE.asi to asi
3033415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 31, 24, ASI);
3043415Sgblack@eecs.umich.edu    //set TSTATE.pstate to pstate
3053415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 20, 8, PSTATE);
3063415Sgblack@eecs.umich.edu    //set TSTATE.cwp to cwp
3073415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 4, 0, CWP);
3083415Sgblack@eecs.umich.edu
3093415Sgblack@eecs.umich.edu    //Write back TSTATE
3103415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TSTATE, TSTATE);
3113415Sgblack@eecs.umich.edu
3123415Sgblack@eecs.umich.edu    //set TPC to PC
3133415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TPC, PC);
3143415Sgblack@eecs.umich.edu    //set TNPC to NPC
3153415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TNPC, NPC);
3163415Sgblack@eecs.umich.edu
3173415Sgblack@eecs.umich.edu    //set HTSTATE.hpstate to hpstate
3183415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
3193415Sgblack@eecs.umich.edu
3203415Sgblack@eecs.umich.edu    //TT = trap type;
3213415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TT, tt);
3223415Sgblack@eecs.umich.edu
3233415Sgblack@eecs.umich.edu    //Update the global register level
3243415Sgblack@eecs.umich.edu    if(1/*We're delivering the trap in priveleged mode*/)
3253572Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
3263415Sgblack@eecs.umich.edu    else
3273572Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxPGL));
3283415Sgblack@eecs.umich.edu
3293415Sgblack@eecs.umich.edu    //PSTATE.mm is unchanged
3303415Sgblack@eecs.umich.edu    //PSTATE.pef = whether or not an fpu is present
3313415Sgblack@eecs.umich.edu    //XXX We'll say there's one present, even though there aren't
3323415Sgblack@eecs.umich.edu    //implementations for a decent number of the instructions
3333415Sgblack@eecs.umich.edu    PSTATE |= (1 << 4);
3343415Sgblack@eecs.umich.edu    //PSTATE.am = 0
3353415Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 3);
3363415Sgblack@eecs.umich.edu    if(1/*We're delivering the trap in priveleged mode*/)
3373415Sgblack@eecs.umich.edu    {
3383415Sgblack@eecs.umich.edu        //PSTATE.priv = 1
3393415Sgblack@eecs.umich.edu        PSTATE |= (1 << 2);
3403415Sgblack@eecs.umich.edu        //PSTATE.cle = PSTATE.tle
3413415Sgblack@eecs.umich.edu        replaceBits(PSTATE, 9, 9, PSTATE >> 8);
3423415Sgblack@eecs.umich.edu    }
3433415Sgblack@eecs.umich.edu    else
3443415Sgblack@eecs.umich.edu    {
3453415Sgblack@eecs.umich.edu        //PSTATE.priv = 0
3463415Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 2);
3473415Sgblack@eecs.umich.edu        //PSTATE.cle = 0
3483415Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 9);
3493415Sgblack@eecs.umich.edu    }
3503415Sgblack@eecs.umich.edu    //PSTATE.ie = 0
3513415Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 1);
3523415Sgblack@eecs.umich.edu    //PSTATE.tle is unchanged
3533415Sgblack@eecs.umich.edu    //PSTATE.tct = 0
3543415Sgblack@eecs.umich.edu    //XXX Where exactly is this field?
3553415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
3563415Sgblack@eecs.umich.edu
3573415Sgblack@eecs.umich.edu    if(0/*We're delivering the trap in hyperprivileged mode*/)
3583415Sgblack@eecs.umich.edu    {
3593415Sgblack@eecs.umich.edu        //HPSTATE.red = 0
3603415Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 5);
3613415Sgblack@eecs.umich.edu        //HPSTATE.hpriv = 1
3623415Sgblack@eecs.umich.edu        HPSTATE |= (1 << 2);
3633415Sgblack@eecs.umich.edu        //HPSTATE.ibe = 0
3643415Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 10);
3653415Sgblack@eecs.umich.edu        //HPSTATE.tlz is unchanged
3663415Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
3673415Sgblack@eecs.umich.edu    }
3683415Sgblack@eecs.umich.edu
3693415Sgblack@eecs.umich.edu    bool changedCWP = true;
3703415Sgblack@eecs.umich.edu    if(tt == 0x24)
3713415Sgblack@eecs.umich.edu        CWP++;
3723415Sgblack@eecs.umich.edu    else if(0x80 <= tt && tt <= 0xbf)
3733415Sgblack@eecs.umich.edu        CWP += (CANSAVE + 2);
3743415Sgblack@eecs.umich.edu    else if(0xc0 <= tt && tt <= 0xff)
3753415Sgblack@eecs.umich.edu        CWP--;
3763415Sgblack@eecs.umich.edu    else
3773415Sgblack@eecs.umich.edu        changedCWP = false;
3783420Sgblack@eecs.umich.edu
3793415Sgblack@eecs.umich.edu    if(changedCWP)
3803415Sgblack@eecs.umich.edu    {
3813415Sgblack@eecs.umich.edu        CWP = (CWP + NWindows) % NWindows;
3823415Sgblack@eecs.umich.edu        tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
3833415Sgblack@eecs.umich.edu    }
3843415Sgblack@eecs.umich.edu}
3853415Sgblack@eecs.umich.edu
3862221SN/A#if FULL_SYSTEM
3872221SN/A
3883573Sgblack@eecs.umich.eduvoid SparcFaultBase::invoke(ThreadContext * tc)
3892221SN/A{
3902680Sktlim@umich.edu    FaultBase::invoke(tc);
3912223SN/A    countStat()++;
3922221SN/A
3932223SN/A    //Use the SPARC trap state machine
3943420Sgblack@eecs.umich.edu}
3952221SN/A
3963523Sgblack@eecs.umich.eduvoid PowerOnReset::invoke(ThreadContext * tc)
3973523Sgblack@eecs.umich.edu{
3983523Sgblack@eecs.umich.edu    //For SPARC, when a system is first started, there is a power
3993523Sgblack@eecs.umich.edu    //on reset Trap which sets the processor into the following state.
4003523Sgblack@eecs.umich.edu    //Bits that aren't set aren't defined on startup.
4013523Sgblack@eecs.umich.edu    /*
4023523Sgblack@eecs.umich.edu    tl = MaxTL;
4033523Sgblack@eecs.umich.edu    gl = MaxGL;
4042221SN/A
4053523Sgblack@eecs.umich.edu    tickFields.counter = 0; //The TICK register is unreadable bya
4063523Sgblack@eecs.umich.edu    tickFields.npt = 1; //The TICK register is unreadable by by !priv
4072221SN/A
4083523Sgblack@eecs.umich.edu    softint = 0; // Clear all the soft interrupt bits
4093523Sgblack@eecs.umich.edu    tick_cmprFields.int_dis = 1; // disable timer compare interrupts
4103523Sgblack@eecs.umich.edu    tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
4113523Sgblack@eecs.umich.edu    stickFields.npt = 1; //The TICK register is unreadable by by !priv
4123523Sgblack@eecs.umich.edu    stick_cmprFields.int_dis = 1; // disable timer compare interrupts
4133523Sgblack@eecs.umich.edu    stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
4143523Sgblack@eecs.umich.edu
4153523Sgblack@eecs.umich.edu    tt[tl] = _trapType;
4163523Sgblack@eecs.umich.edu    pstate = 0; // fields 0 but pef
4173523Sgblack@eecs.umich.edu    pstateFields.pef = 1;
4183523Sgblack@eecs.umich.edu
4193523Sgblack@eecs.umich.edu    hpstate = 0;
4203523Sgblack@eecs.umich.edu    hpstateFields.red = 1;
4213523Sgblack@eecs.umich.edu    hpstateFields.hpriv = 1;
4223523Sgblack@eecs.umich.edu    hpstateFields.tlz = 0; // this is a guess
4233523Sgblack@eecs.umich.edu    hintp = 0; // no interrupts pending
4243523Sgblack@eecs.umich.edu    hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
4253523Sgblack@eecs.umich.edu    hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
4263523Sgblack@eecs.umich.edu    */
4272221SN/A}
4282221SN/A
4292612SN/A#endif
4302612SN/A
4312612SN/A#if !FULL_SYSTEM
4322612SN/A
4333415Sgblack@eecs.umich.eduvoid SpillNNormal::invoke(ThreadContext *tc)
4343415Sgblack@eecs.umich.edu{
4353415Sgblack@eecs.umich.edu    doNormalFault(tc, trapType());
4363415Sgblack@eecs.umich.edu
4373415Sgblack@eecs.umich.edu    Process *p = tc->getProcessPtr();
4383415Sgblack@eecs.umich.edu
4393415Sgblack@eecs.umich.edu    //This will only work in faults from a SparcLiveProcess
4403415Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
4413415Sgblack@eecs.umich.edu    assert(lp);
4423415Sgblack@eecs.umich.edu
4433415Sgblack@eecs.umich.edu    //Then adjust the PC and NPC
4443415Sgblack@eecs.umich.edu    Addr spillStart = lp->readSpillStart();
4453415Sgblack@eecs.umich.edu    tc->setPC(spillStart);
4463415Sgblack@eecs.umich.edu    tc->setNextPC(spillStart + sizeof(MachInst));
4473415Sgblack@eecs.umich.edu    tc->setNextNPC(spillStart + 2*sizeof(MachInst));
4483415Sgblack@eecs.umich.edu}
4493415Sgblack@eecs.umich.edu
4503415Sgblack@eecs.umich.eduvoid FillNNormal::invoke(ThreadContext *tc)
4513415Sgblack@eecs.umich.edu{
4523415Sgblack@eecs.umich.edu    doNormalFault(tc, trapType());
4533415Sgblack@eecs.umich.edu
4543415Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
4553415Sgblack@eecs.umich.edu
4563415Sgblack@eecs.umich.edu    //This will only work in faults from a SparcLiveProcess
4573415Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
4583415Sgblack@eecs.umich.edu    assert(lp);
4593415Sgblack@eecs.umich.edu
4603415Sgblack@eecs.umich.edu    //The adjust the PC and NPC
4613415Sgblack@eecs.umich.edu    Addr fillStart = lp->readFillStart();
4623415Sgblack@eecs.umich.edu    tc->setPC(fillStart);
4633415Sgblack@eecs.umich.edu    tc->setNextPC(fillStart + sizeof(MachInst));
4643415Sgblack@eecs.umich.edu    tc->setNextNPC(fillStart + 2*sizeof(MachInst));
4653415Sgblack@eecs.umich.edu}
4663415Sgblack@eecs.umich.edu
4672800Ssaidi@eecs.umich.eduvoid PageTableFault::invoke(ThreadContext *tc)
4682800Ssaidi@eecs.umich.edu{
4692800Ssaidi@eecs.umich.edu    Process *p = tc->getProcessPtr();
4702800Ssaidi@eecs.umich.edu
4712800Ssaidi@eecs.umich.edu    // address is higher than the stack region or in the current stack region
4722800Ssaidi@eecs.umich.edu    if (vaddr > p->stack_base || vaddr > p->stack_min)
4732800Ssaidi@eecs.umich.edu        FaultBase::invoke(tc);
4742800Ssaidi@eecs.umich.edu
4752800Ssaidi@eecs.umich.edu    // We've accessed the next page
4762800Ssaidi@eecs.umich.edu    if (vaddr > p->stack_min - PageBytes) {
4772800Ssaidi@eecs.umich.edu        p->stack_min -= PageBytes;
4782800Ssaidi@eecs.umich.edu        if (p->stack_base - p->stack_min > 8*1024*1024)
4792800Ssaidi@eecs.umich.edu            fatal("Over max stack size for one thread\n");
4802800Ssaidi@eecs.umich.edu        p->pTable->allocate(p->stack_min, PageBytes);
4812800Ssaidi@eecs.umich.edu        warn("Increasing stack size by one page.");
4822800Ssaidi@eecs.umich.edu    } else {
4832800Ssaidi@eecs.umich.edu        FaultBase::invoke(tc);
4842800Ssaidi@eecs.umich.edu    }
4852800Ssaidi@eecs.umich.edu}
4863415Sgblack@eecs.umich.edu
4872221SN/A#endif
4882221SN/A
4892223SN/A} // namespace SparcISA
4902221SN/A
491