faults.cc revision 4103
1360SN/A/*
21458SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
3360SN/A * All rights reserved.
4360SN/A *
5360SN/A * Redistribution and use in source and binary forms, with or without
6360SN/A * modification, are permitted provided that the following conditions are
7360SN/A * met: redistributions of source code must retain the above copyright
8360SN/A * notice, this list of conditions and the following disclaimer;
9360SN/A * redistributions in binary form must reproduce the above copyright
10360SN/A * notice, this list of conditions and the following disclaimer in the
11360SN/A * documentation and/or other materials provided with the distribution;
12360SN/A * neither the name of the copyright holders nor the names of its
13360SN/A * contributors may be used to endorse or promote products derived from
14360SN/A * this software without specific prior written permission.
15360SN/A *
16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26360SN/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
30360SN/A */
31360SN/A
321354SN/A#include <algorithm>
331354SN/A
34360SN/A#include "arch/sparc/faults.hh"
352764Sstever@eecs.umich.edu#include "arch/sparc/isa_traits.hh"
362764Sstever@eecs.umich.edu#include "arch/sparc/types.hh"
372064SN/A#include "base/bitfield.hh"
38360SN/A#include "base/trace.hh"
39360SN/A#include "config/full_system.hh"
40360SN/A#include "cpu/base.hh"
41360SN/A#include "cpu/thread_context.hh"
42360SN/A#if !FULL_SYSTEM
43360SN/A#include "arch/sparc/process.hh"
441809SN/A#include "mem/page_table.hh"
455543Ssaidi@eecs.umich.edu#include "sim/process.hh"
461809SN/A#endif
473113Sgblack@eecs.umich.edu
488229Snate@binkert.orgusing namespace std;
498229Snate@binkert.org
503113Sgblack@eecs.umich.edunamespace SparcISA
517075Snate@binkert.org{
528229Snate@binkert.org
537075Snate@binkert.orgtemplate<> SparcFaultBase::FaultVals
54360SN/A    SparcFault<PowerOnReset>::vals =
552474SN/A    {"power_on_reset", 0x001, 0, {H, H, H}};
565543Ssaidi@eecs.umich.edu
572462SN/Atemplate<> SparcFaultBase::FaultVals
581354SN/A    SparcFault<WatchDogReset>::vals =
596216Snate@binkert.org    {"watch_dog_reset", 0x002, 120, {H, H, H}};
606658Snate@binkert.org
612474SN/Atemplate<> SparcFaultBase::FaultVals
622680Sktlim@umich.edu    SparcFault<ExternallyInitiatedReset>::vals =
638232Snate@binkert.org    {"externally_initiated_reset", 0x003, 110, {H, H, H}};
648229Snate@binkert.org
658706Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals
667678Sgblack@eecs.umich.edu    SparcFault<SoftwareInitiatedReset>::vals =
678229Snate@binkert.org    {"software_initiated_reset", 0x004, 130, {SH, SH, H}};
688766Sgblack@eecs.umich.edu
696640Svince@csl.cornell.edutemplate<> SparcFaultBase::FaultVals
70360SN/A    SparcFault<REDStateException>::vals =
71360SN/A    {"RED_state_exception", 0x005, 1, {H, H, H}};
72360SN/A
73360SN/Atemplate<> SparcFaultBase::FaultVals
74360SN/A    SparcFault<StoreError>::vals =
75360SN/A    {"store_error", 0x007, 201, {H, H, H}};
76360SN/A
77360SN/Atemplate<> SparcFaultBase::FaultVals
78378SN/A    SparcFault<InstructionAccessException>::vals =
791450SN/A    {"instruction_access_exception", 0x008, 300, {H, H, H}};
803114Sgblack@eecs.umich.edu
81360SN/A//XXX This trap is apparently dropped from ua2005
825543Ssaidi@eecs.umich.edu/*template<> SparcFaultBase::FaultVals
835543Ssaidi@eecs.umich.edu    SparcFault<InstructionAccessMMUMiss>::vals =
845543Ssaidi@eecs.umich.edu    {"inst_mmu", 0x009, 2, {H, H, H}};*/
85360SN/A
86360SN/Atemplate<> SparcFaultBase::FaultVals
87360SN/A    SparcFault<InstructionAccessError>::vals =
88360SN/A    {"instruction_access_error", 0x00A, 400, {H, H, H}};
89360SN/A
902680Sktlim@umich.edutemplate<> SparcFaultBase::FaultVals
91360SN/A    SparcFault<IllegalInstruction>::vals =
92360SN/A    {"illegal_instruction", 0x010, 620, {H, H, H}};
93360SN/A
94360SN/Atemplate<> SparcFaultBase::FaultVals
95360SN/A    SparcFault<PrivilegedOpcode>::vals =
96360SN/A    {"privileged_opcode", 0x011, 700, {P, SH, SH}};
97360SN/A
98360SN/A//XXX This trap is apparently dropped from ua2005
99360SN/A/*template<> SparcFaultBase::FaultVals
100360SN/A    SparcFault<UnimplementedLDD>::vals =
101360SN/A    {"unimp_ldd", 0x012, 6, {H, H, H}};*/
1023114Sgblack@eecs.umich.edu
103360SN/A//XXX This trap is apparently dropped from ua2005
104360SN/A/*template<> SparcFaultBase::FaultVals
105360SN/A    SparcFault<UnimplementedSTD>::vals =
106360SN/A    {"unimp_std", 0x013, 6, {H, H, H}};*/
107360SN/A
108360SN/Atemplate<> SparcFaultBase::FaultVals
109360SN/A    SparcFault<FpDisabled>::vals =
110360SN/A    {"fp_disabled", 0x020, 800, {P, P, H}};
111360SN/A
112360SN/Atemplate<> SparcFaultBase::FaultVals
113360SN/A    SparcFault<FpExceptionIEEE754>::vals =
114360SN/A    {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}};
115360SN/A
116360SN/Atemplate<> SparcFaultBase::FaultVals
117360SN/A    SparcFault<FpExceptionOther>::vals =
118360SN/A    {"fp_exception_other", 0x022, 1110, {P, P, H}};
119360SN/A
120360SN/Atemplate<> SparcFaultBase::FaultVals
121360SN/A    SparcFault<TagOverflow>::vals =
122360SN/A    {"tag_overflow", 0x023, 1400, {P, P, H}};
123360SN/A
1248852Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals
125360SN/A    SparcFault<CleanWindow>::vals =
1268852Sandreas.hansson@arm.com    {"clean_window", 0x024, 1010, {P, P, H}};
1275543Ssaidi@eecs.umich.edu
128360SN/Atemplate<> SparcFaultBase::FaultVals
129360SN/A    SparcFault<DivisionByZero>::vals =
130360SN/A    {"division_by_zero", 0x028, 1500, {P, P, H}};
131360SN/A
132360SN/Atemplate<> SparcFaultBase::FaultVals
1338852Sandreas.hansson@arm.com    SparcFault<InternalProcessorError>::vals =
134360SN/A    {"internal_processor_error", 0x029, 4, {H, H, H}};
1358852Sandreas.hansson@arm.com
1365543Ssaidi@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
137360SN/A    SparcFault<InstructionInvalidTSBEntry>::vals =
138360SN/A    {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}};
139360SN/A
140360SN/Atemplate<> SparcFaultBase::FaultVals
141360SN/A    SparcFault<DataInvalidTSBEntry>::vals =
142360SN/A    {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}};
143360SN/A
144360SN/Atemplate<> SparcFaultBase::FaultVals
145360SN/A    SparcFault<DataAccessException>::vals =
146360SN/A    {"data_access_exception", 0x030, 1201, {H, H, H}};
147360SN/A
148360SN/A//XXX This trap is apparently dropped from ua2005
149360SN/A/*template<> SparcFaultBase::FaultVals
1505543Ssaidi@eecs.umich.edu    SparcFault<DataAccessMMUMiss>::vals =
151360SN/A    {"data_mmu", 0x031, 12, {H, H, H}};*/
152360SN/A
153360SN/Atemplate<> SparcFaultBase::FaultVals
154360SN/A    SparcFault<DataAccessError>::vals =
155360SN/A    {"data_access_error", 0x032, 1210, {H, H, H}};
156360SN/A
157360SN/Atemplate<> SparcFaultBase::FaultVals
158360SN/A    SparcFault<DataAccessProtection>::vals =
159360SN/A    {"data_access_protection", 0x033, 1207, {H, H, H}};
160360SN/A
161360SN/Atemplate<> SparcFaultBase::FaultVals
162360SN/A    SparcFault<MemAddressNotAligned>::vals =
163360SN/A    {"mem_address_not_aligned", 0x034, 1020, {H, H, H}};
164360SN/A
165360SN/Atemplate<> SparcFaultBase::FaultVals
166360SN/A    SparcFault<LDDFMemAddressNotAligned>::vals =
167360SN/A    {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}};
1685543Ssaidi@eecs.umich.edu
1695543Ssaidi@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
170502SN/A    SparcFault<STDFMemAddressNotAligned>::vals =
171360SN/A    {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}};
172360SN/A
173360SN/Atemplate<> SparcFaultBase::FaultVals
174360SN/A    SparcFault<PrivilegedAction>::vals =
175360SN/A    {"privileged_action", 0x037, 1110, {H, H, SH}};
176360SN/A
177360SN/Atemplate<> SparcFaultBase::FaultVals
178360SN/A    SparcFault<LDQFMemAddressNotAligned>::vals =
179360SN/A    {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}};
180360SN/A
181360SN/Atemplate<> SparcFaultBase::FaultVals
182378SN/A    SparcFault<STQFMemAddressNotAligned>::vals =
1831706SN/A    {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}};
1843114Sgblack@eecs.umich.edu
185378SN/Atemplate<> SparcFaultBase::FaultVals
186378SN/A    SparcFault<InstructionRealTranslationMiss>::vals =
187378SN/A    {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}};
188378SN/A
189378SN/Atemplate<> SparcFaultBase::FaultVals
1901706SN/A    SparcFault<DataRealTranslationMiss>::vals =
1913114Sgblack@eecs.umich.edu    {"data_real_translation_miss", 0x03F, 1203, {H, H, H}};
1928149SChris.Emmons@ARM.com
1938149SChris.Emmons@ARM.com//XXX This trap is apparently dropped from ua2005
194360SN/A/*template<> SparcFaultBase::FaultVals
1956109Ssanchezd@stanford.edu    SparcFault<AsyncDataError>::vals =
1961706SN/A    {"async_data", 0x040, 2, {H, H, H}};*/
1973114Sgblack@eecs.umich.edu
198378SN/Atemplate<> SparcFaultBase::FaultVals
1996109Ssanchezd@stanford.edu    SparcFault<InterruptLevelN>::vals =
2006109Ssanchezd@stanford.edu    {"interrupt_level_n", 0x040, 0, {P, P, SH}};
2016109Ssanchezd@stanford.edu
2026109Ssanchezd@stanford.edutemplate<> SparcFaultBase::FaultVals
203378SN/A    SparcFault<HstickMatch>::vals =
2041706SN/A    {"hstick_match", 0x05E, 1601, {H, H, H}};
2053114Sgblack@eecs.umich.edu
206378SN/Atemplate<> SparcFaultBase::FaultVals
2075748SSteve.Reinhardt@amd.com    SparcFault<TrapLevelZero>::vals =
2085748SSteve.Reinhardt@amd.com    {"trap_level_zero", 0x05F, 202, {H, H, SH}};
2095748SSteve.Reinhardt@amd.com
210378SN/Atemplate<> SparcFaultBase::FaultVals
211378SN/A    SparcFault<InterruptVector>::vals =
2121706SN/A    {"interrupt_vector", 0x060, 2630, {H, H, H}};
2133114Sgblack@eecs.umich.edu
214378SN/Atemplate<> SparcFaultBase::FaultVals
215378SN/A    SparcFault<PAWatchpoint>::vals =
2161706SN/A    {"PA_watchpoint", 0x061, 1209, {H, H, H}};
2173114Sgblack@eecs.umich.edu
218378SN/Atemplate<> SparcFaultBase::FaultVals
219378SN/A    SparcFault<VAWatchpoint>::vals =
2201706SN/A    {"VA_watchpoint", 0x062, 1120, {P, P, SH}};
2213114Sgblack@eecs.umich.edu
222378SN/Atemplate<> SparcFaultBase::FaultVals
223378SN/A    SparcFault<FastInstructionAccessMMUMiss>::vals =
2241706SN/A    {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}};
2253114Sgblack@eecs.umich.edu
226378SN/Atemplate<> SparcFaultBase::FaultVals
2274118Sgblack@eecs.umich.edu    SparcFault<FastDataAccessMMUMiss>::vals =
2284118Sgblack@eecs.umich.edu    {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}};
2294118Sgblack@eecs.umich.edu
2304118Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
231378SN/A    SparcFault<FastDataAccessProtection>::vals =
2321706SN/A    {"fast_data_access_protection", 0x06C, 1207, {H, H, H}};
2333114Sgblack@eecs.umich.edu
234378SN/Atemplate<> SparcFaultBase::FaultVals
235378SN/A    SparcFault<InstructionBreakpoint>::vals =
2361706SN/A    {"instruction_break", 0x076, 610, {H, H, H}};
2373114Sgblack@eecs.umich.edu
238360SN/Atemplate<> SparcFaultBase::FaultVals
2395513SMichael.Adler@intel.com    SparcFault<CpuMondo>::vals =
2405513SMichael.Adler@intel.com    {"cpu_mondo", 0x07C, 1608, {P, P, SH}};
2415513SMichael.Adler@intel.com
2425513SMichael.Adler@intel.comtemplate<> SparcFaultBase::FaultVals
2435513SMichael.Adler@intel.com    SparcFault<DevMondo>::vals =
2445513SMichael.Adler@intel.com    {"dev_mondo", 0x07D, 1611, {P, P, SH}};
2455513SMichael.Adler@intel.com
2465513SMichael.Adler@intel.comtemplate<> SparcFaultBase::FaultVals
247511SN/A    SparcFault<ResumableError>::vals =
2481706SN/A    {"resume_error", 0x07E, 3330, {P, P, SH}};
2493114Sgblack@eecs.umich.edu
250511SN/Atemplate<> SparcFaultBase::FaultVals
2515513SMichael.Adler@intel.com    SparcFault<SpillNNormal>::vals =
2525513SMichael.Adler@intel.com    {"spill_n_normal", 0x080, 900, {P, P, H}};
2535513SMichael.Adler@intel.com
2545513SMichael.Adler@intel.comtemplate<> SparcFaultBase::FaultVals
255511SN/A    SparcFault<SpillNOther>::vals =
2561706SN/A    {"spill_n_other", 0x0A0, 900, {P, P, H}};
2573114Sgblack@eecs.umich.edu
2581706SN/Atemplate<> SparcFaultBase::FaultVals
2591706SN/A    SparcFault<FillNNormal>::vals =
2601706SN/A    {"fill_n_normal", 0x0C0, 900, {P, P, H}};
2611706SN/A
2623114Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals
2631706SN/A    SparcFault<FillNOther>::vals =
2641706SN/A    {"fill_n_other", 0x0E0, 900, {P, P, H}};
2651706SN/A
2661706SN/Atemplate<> SparcFaultBase::FaultVals
2673114Sgblack@eecs.umich.edu    SparcFault<TrapInstruction>::vals =
2681706SN/A    {"trap_instruction", 0x100, 1602, {P, P, H}};
269511SN/A
2706703Svince@csl.cornell.edu#if !FULL_SYSTEM
2716703Svince@csl.cornell.edutemplate<> SparcFaultBase::FaultVals
2726703Svince@csl.cornell.edu    SparcFault<PageTableFault>::vals =
2736703Svince@csl.cornell.edu    {"page_table_fault", 0x0000, 0, {SH, SH, SH}};
2746685Stjones1@inf.ed.ac.uk#endif
2756685Stjones1@inf.ed.ac.uk
2766685Stjones1@inf.ed.ac.uk/**
2776685Stjones1@inf.ed.ac.uk * This causes the thread context to enter RED state. This causes the side
2786685Stjones1@inf.ed.ac.uk * effects which go with entering RED state because of a trap.
2795513SMichael.Adler@intel.com */
2805513SMichael.Adler@intel.com
2815513SMichael.Adler@intel.comvoid enterREDState(ThreadContext *tc)
2825513SMichael.Adler@intel.com{
2835513SMichael.Adler@intel.com    //@todo Disable the mmu?
2841999SN/A    //@todo Disable watchpoints?
2851999SN/A    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
2863114Sgblack@eecs.umich.edu    //HPSTATE.red = 1
2871999SN/A    HPSTATE |= (1 << 5);
2881999SN/A    //HPSTATE.hpriv = 1
2891999SN/A    HPSTATE |= (1 << 2);
2901999SN/A    tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE);
2913114Sgblack@eecs.umich.edu    //PSTATE.priv is set to 1 here. The manual says it should be 0, but
2921999SN/A    //Legion sets it to 1.
2933079Sstever@eecs.umich.edu    MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
2943079Sstever@eecs.umich.edu    PSTATE |= (1 << 2);
2953114Sgblack@eecs.umich.edu    tc->setMiscRegWithEffect(MISCREG_PSTATE, PSTATE);
2963079Sstever@eecs.umich.edu}
2972093SN/A
2982093SN/A/**
2993114Sgblack@eecs.umich.edu * This sets everything up for a RED state trap except for actually jumping to
3002093SN/A * the handler.
3012687Sksewell@umich.edu */
3022687Sksewell@umich.edu
3033114Sgblack@eecs.umich.eduvoid doREDFault(ThreadContext *tc, TrapType tt)
3042687Sksewell@umich.edu{
3052238SN/A    MiscReg TL = tc->readMiscReg(MISCREG_TL);
3062238SN/A    MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
3073114Sgblack@eecs.umich.edu    MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
3082238SN/A    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
3092238SN/A    //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
3102238SN/A    MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
3113114Sgblack@eecs.umich.edu    MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
3122238SN/A    MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
3132238SN/A    //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
3142238SN/A    MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3);
3153114Sgblack@eecs.umich.edu    MiscReg GL = tc->readMiscReg(MISCREG_GL);
3162238SN/A    MiscReg PC = tc->readPC();
3172238SN/A    MiscReg NPC = tc->readNextPC();
3182238SN/A
3193114Sgblack@eecs.umich.edu    TL++;
3202238SN/A
3212238SN/A    if (bits(PSTATE, 3,3)) {
3222238SN/A        PC &= mask(32);
3233114Sgblack@eecs.umich.edu        NPC &= mask(32);
3242238SN/A    }
3252238SN/A
3262238SN/A    //set TSTATE.gl to gl
3273114Sgblack@eecs.umich.edu    replaceBits(TSTATE, 42, 40, GL);
3282238SN/A    //set TSTATE.ccr to ccr
3292238SN/A    replaceBits(TSTATE, 39, 32, CCR);
3302238SN/A    //set TSTATE.asi to asi
3313114Sgblack@eecs.umich.edu    replaceBits(TSTATE, 31, 24, ASI);
3322238SN/A    //set TSTATE.pstate to pstate
3336109Ssanchezd@stanford.edu    replaceBits(TSTATE, 20, 8, PSTATE);
3346109Ssanchezd@stanford.edu    //set TSTATE.cwp to cwp
3356109Ssanchezd@stanford.edu    replaceBits(TSTATE, 4, 0, CWP);
3362238SN/A
3372238SN/A    //Write back TSTATE
3382238SN/A    tc->setMiscReg(MISCREG_TSTATE, TSTATE);
3392238SN/A
3402238SN/A    //set TPC to PC
3413114Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TPC, PC);
3422238SN/A    //set TNPC to NPC
3432238SN/A    tc->setMiscReg(MISCREG_TNPC, NPC);
3442238SN/A
3453114Sgblack@eecs.umich.edu    //set HTSTATE.hpstate to hpstate
3462238SN/A    tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
3472238SN/A
3482238SN/A    //TT = trap type;
3493114Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TT, tt);
3502238SN/A
3512238SN/A    //Update GL
3522238SN/A    tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
3533114Sgblack@eecs.umich.edu
3542238SN/A    PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
3552238SN/A    PSTATE |= (1 << 4); //set PSTATE.pef to 1
3561354SN/A    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
3571354SN/A
3581354SN/A    //set HPSTATE.red to 1
3591354SN/A    HPSTATE |= (1 << 5);
3601354SN/A    //set HPSTATE.hpriv to 1
3611354SN/A    HPSTATE |= (1 << 2);
3621354SN/A    //set HPSTATE.ibe to 0
3631354SN/A    HPSTATE &= ~(1 << 10);
3641354SN/A    //set HPSTATE.tlz to 0
3651354SN/A    HPSTATE &= ~(1 << 0);
3661354SN/A    tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
3671354SN/A
3681354SN/A    bool changedCWP = true;
3691354SN/A    if(tt == 0x24)
3707823Ssteve.reinhardt@amd.com        CWP++;
3711354SN/A    else if(0x80 <= tt && tt <= 0xbf)
3721354SN/A        CWP += (CANSAVE + 2);
3731354SN/A    else if(0xc0 <= tt && tt <= 0xff)
3741354SN/A        CWP--;
375360SN/A    else
376360SN/A        changedCWP = false;
377360SN/A
378360SN/A    if(changedCWP)
379360SN/A    {
380360SN/A        CWP = (CWP + NWindows) % NWindows;
381360SN/A        tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
3823113Sgblack@eecs.umich.edu    }
3833113Sgblack@eecs.umich.edu}
3843113Sgblack@eecs.umich.edu
3853113Sgblack@eecs.umich.edu/**
3863113Sgblack@eecs.umich.edu * This sets everything up for a normal trap except for actually jumping to
3873113Sgblack@eecs.umich.edu * the handler.
3883113Sgblack@eecs.umich.edu */
3893113Sgblack@eecs.umich.edu
3903113Sgblack@eecs.umich.eduvoid doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
3913113Sgblack@eecs.umich.edu{
3923113Sgblack@eecs.umich.edu    MiscReg TL = tc->readMiscReg(MISCREG_TL);
3933113Sgblack@eecs.umich.edu    MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
3943113Sgblack@eecs.umich.edu    MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
3953113Sgblack@eecs.umich.edu    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
3963113Sgblack@eecs.umich.edu    //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
3973113Sgblack@eecs.umich.edu    MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
3984189Sgblack@eecs.umich.edu    MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
3994189Sgblack@eecs.umich.edu    MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
4003113Sgblack@eecs.umich.edu    //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
4013113Sgblack@eecs.umich.edu    MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
4023113Sgblack@eecs.umich.edu    MiscReg GL = tc->readMiscReg(MISCREG_GL);
4033113Sgblack@eecs.umich.edu    MiscReg PC = tc->readPC();
4048737Skoansin.tan@gmail.com    MiscReg NPC = tc->readNextPC();
4053113Sgblack@eecs.umich.edu
4068737Skoansin.tan@gmail.com    if (bits(PSTATE, 3,3)) {
4073277Sgblack@eecs.umich.edu        PC &= mask(32);
4085515SMichael.Adler@intel.com        NPC &= mask(32);
4095515SMichael.Adler@intel.com    }
4105515SMichael.Adler@intel.com
4115515SMichael.Adler@intel.com    //Increment the trap level
4125515SMichael.Adler@intel.com    TL++;
4138737Skoansin.tan@gmail.com    tc->setMiscReg(MISCREG_TL, TL);
4143277Sgblack@eecs.umich.edu
4158737Skoansin.tan@gmail.com    //Save off state
4163277Sgblack@eecs.umich.edu
4178737Skoansin.tan@gmail.com    //set TSTATE.gl to gl
4183277Sgblack@eecs.umich.edu    replaceBits(TSTATE, 42, 40, GL);
4198737Skoansin.tan@gmail.com    //set TSTATE.ccr to ccr
4203113Sgblack@eecs.umich.edu    replaceBits(TSTATE, 39, 32, CCR);
4213113Sgblack@eecs.umich.edu    //set TSTATE.asi to asi
4223113Sgblack@eecs.umich.edu    replaceBits(TSTATE, 31, 24, ASI);
4233113Sgblack@eecs.umich.edu    //set TSTATE.pstate to pstate
4248737Skoansin.tan@gmail.com    replaceBits(TSTATE, 20, 8, PSTATE);
4253113Sgblack@eecs.umich.edu    //set TSTATE.cwp to cwp
4268737Skoansin.tan@gmail.com    replaceBits(TSTATE, 4, 0, CWP);
4273114Sgblack@eecs.umich.edu
4288737Skoansin.tan@gmail.com    //Write back TSTATE
4293114Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TSTATE, TSTATE);
4308737Skoansin.tan@gmail.com
4313114Sgblack@eecs.umich.edu    //set TPC to PC
4328737Skoansin.tan@gmail.com    tc->setMiscReg(MISCREG_TPC, PC);
4334061Sgblack@eecs.umich.edu    //set TNPC to NPC
4344061Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TNPC, NPC);
4354061Sgblack@eecs.umich.edu
4368737Skoansin.tan@gmail.com    //set HTSTATE.hpstate to hpstate
4373113Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
4388737Skoansin.tan@gmail.com
4393113Sgblack@eecs.umich.edu    //TT = trap type;
4403113Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TT, tt);
4413113Sgblack@eecs.umich.edu
4423113Sgblack@eecs.umich.edu    //Update the global register level
4433113Sgblack@eecs.umich.edu    if (!gotoHpriv)
4443113Sgblack@eecs.umich.edu        tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
4453113Sgblack@eecs.umich.edu    else
4463113Sgblack@eecs.umich.edu        tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
4474189Sgblack@eecs.umich.edu
4484189Sgblack@eecs.umich.edu    //PSTATE.mm is unchanged
4493113Sgblack@eecs.umich.edu    PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present
4503113Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 3); //PSTATE.am = 0
4513113Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 1); //PSTATE.ie = 0
4528737Skoansin.tan@gmail.com    //PSTATE.tle is unchanged
4533113Sgblack@eecs.umich.edu    //PSTATE.tct = 0
4548737Skoansin.tan@gmail.com
4553113Sgblack@eecs.umich.edu    if (gotoHpriv)
4568737Skoansin.tan@gmail.com    {
4573113Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 9); // PSTATE.cle = 0
4583113Sgblack@eecs.umich.edu        //The manual says PSTATE.priv should be 0, but Legion leaves it alone
4593113Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 5); //HPSTATE.red = 0
4603113Sgblack@eecs.umich.edu        HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1
4613113Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0
4623113Sgblack@eecs.umich.edu        //HPSTATE.tlz is unchanged
4633113Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
4643113Sgblack@eecs.umich.edu    } else { // we are going to priv
4653113Sgblack@eecs.umich.edu        PSTATE |= (1 << 2); //PSTATE.priv = 1
4663113Sgblack@eecs.umich.edu        replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle
4678852Sandreas.hansson@arm.com    }
4683113Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
4693113Sgblack@eecs.umich.edu
4703113Sgblack@eecs.umich.edu
4713113Sgblack@eecs.umich.edu    bool changedCWP = true;
4723113Sgblack@eecs.umich.edu    if (tt == 0x24)
4733113Sgblack@eecs.umich.edu        CWP++;
4743113Sgblack@eecs.umich.edu    else if (0x80 <= tt && tt <= 0xbf)
4753113Sgblack@eecs.umich.edu        CWP += (CANSAVE + 2);
4763113Sgblack@eecs.umich.edu    else if (0xc0 <= tt && tt <= 0xff)
4773113Sgblack@eecs.umich.edu        CWP--;
4788852Sandreas.hansson@arm.com    else
4793113Sgblack@eecs.umich.edu        changedCWP = false;
4803113Sgblack@eecs.umich.edu
4813113Sgblack@eecs.umich.edu    if (changedCWP)
4823113Sgblack@eecs.umich.edu    {
4836686Stjones1@inf.ed.ac.uk        CWP = (CWP + NWindows) % NWindows;
4843113Sgblack@eecs.umich.edu        tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
4853113Sgblack@eecs.umich.edu    }
4863113Sgblack@eecs.umich.edu}
487378SN/A
488378SN/Avoid getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
489378SN/A{
490360SN/A    //XXX The following constant might belong in a header file.
4911450SN/A    const Addr RSTVAddr = 0xFFF0000000ULL;
4923114Sgblack@eecs.umich.edu    PC = RSTVAddr | ((TT << 5) & 0xFF);
4932680Sktlim@umich.edu    NPC = PC + sizeof(MachInst);
494360SN/A}
4956701Sgblack@eecs.umich.edu
4966701Sgblack@eecs.umich.eduvoid getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT)
4976701Sgblack@eecs.umich.edu{
498360SN/A    Addr HTBA = tc->readMiscReg(MISCREG_HTBA);
4991969SN/A    PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
500360SN/A    NPC = PC + sizeof(MachInst);
501360SN/A}
502360SN/A
5031458SN/Avoid getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL)
504360SN/A{
505360SN/A    Addr TBA = tc->readMiscReg(MISCREG_TBA);
506360SN/A    PC = (TBA & ~mask(15)) |
5074131Sbinkertn@umich.edu        (TL > 1 ? (1 << 14) : 0) |
5084131Sbinkertn@umich.edu        ((TT << 5) & mask(14));
5094131Sbinkertn@umich.edu    NPC = PC + sizeof(MachInst);
5104131Sbinkertn@umich.edu}
5114131Sbinkertn@umich.edu
5124131Sbinkertn@umich.edu#if FULL_SYSTEM
5134131Sbinkertn@umich.edu
5144131Sbinkertn@umich.eduvoid SparcFaultBase::invoke(ThreadContext * tc)
5156689Stjones1@inf.ed.ac.uk{
5161458SN/A    //panic("Invoking a second fault!\n");
517360SN/A    FaultBase::invoke(tc);
518360SN/A    countStat()++;
5197720Sgblack@eecs.umich.edu
5207720Sgblack@eecs.umich.edu    //We can refer to this to see what the trap level -was-, but something
521360SN/A    //in the middle could change it in the regfile out from under us.
522360SN/A    MiscReg tl = tc->readMiscReg(MISCREG_TL);
523360SN/A    MiscReg tt = tc->readMiscReg(MISCREG_TT);
524378SN/A    MiscReg pstate = tc->readMiscReg(MISCREG_PSTATE);
525360SN/A    MiscReg hpstate = tc->readMiscReg(MISCREG_HPSTATE);
5261450SN/A
5273114Sgblack@eecs.umich.edu    Addr PC, NPC;
5282680Sktlim@umich.edu
529360SN/A    PrivilegeLevel current;
530360SN/A    if (hpstate & HPSTATE::hpriv)
531360SN/A        current = Hyperprivileged;
5326701Sgblack@eecs.umich.edu    else if (pstate & PSTATE::priv)
5338852Sandreas.hansson@arm.com        current = Privileged;
5346701Sgblack@eecs.umich.edu    else
5351458SN/A        current = User;
536360SN/A
537360SN/A    PrivilegeLevel level = getNextLevel(current);
538360SN/A
539360SN/A    if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) {
5401706SN/A        getREDVector(5, PC, NPC);
5411458SN/A        doREDFault(tc, tt);
542360SN/A        //This changes the hpstate and pstate, so we need to make sure we
543360SN/A        //save the old version on the trap stack in doREDFault.
5446701Sgblack@eecs.umich.edu        enterREDState(tc);
5456701Sgblack@eecs.umich.edu    } else if (tl == MaxTL) {
546360SN/A        panic("Should go to error state here.. crap\n");
547360SN/A        //Do error_state somehow?
548360SN/A        //Probably inject a WDR fault using the interrupt mechanism.
549360SN/A        //What should the PC and NPC be set to?
550360SN/A    } else if (tl > MaxPTL && level == Privileged) {
551360SN/A        //guest_watchdog fault
552360SN/A        doNormalFault(tc, trapType(), true);
553360SN/A        getHyperVector(tc, PC, NPC, 2);
554360SN/A    } else if (level == Hyperprivileged ||
555360SN/A            level == Privileged && trapType() >= 384) {
556360SN/A        doNormalFault(tc, trapType(), true);
557360SN/A        getHyperVector(tc, PC, NPC, trapType());
5581706SN/A    } else {
559360SN/A        doNormalFault(tc, trapType(), false);
560360SN/A        getPrivVector(tc, PC, NPC, trapType(), tl+1);
561360SN/A    }
562360SN/A
563360SN/A    tc->setPC(PC);
5643669Sbinkertn@umich.edu    tc->setNextPC(NPC);
5653669Sbinkertn@umich.edu    tc->setNextNPC(NPC + sizeof(MachInst));
5663669Sbinkertn@umich.edu}
5671706SN/A
5681706SN/Avoid PowerOnReset::invoke(ThreadContext * tc)
5695795Ssaidi@eecs.umich.edu{
5705795Ssaidi@eecs.umich.edu    //For SPARC, when a system is first started, there is a power
5715795Ssaidi@eecs.umich.edu    //on reset Trap which sets the processor into the following state.
5725795Ssaidi@eecs.umich.edu    //Bits that aren't set aren't defined on startup.
5735795Ssaidi@eecs.umich.edu
5745795Ssaidi@eecs.umich.edu    tc->setMiscReg(MISCREG_TL, MaxTL);
5755795Ssaidi@eecs.umich.edu    tc->setMiscReg(MISCREG_TT, trapType());
5765795Ssaidi@eecs.umich.edu    tc->setMiscRegWithEffect(MISCREG_GL, MaxGL);
5775795Ssaidi@eecs.umich.edu
5785795Ssaidi@eecs.umich.edu    //Turn on pef and priv, set everything else to 0
5795795Ssaidi@eecs.umich.edu    tc->setMiscReg(MISCREG_PSTATE, (1 << 4) | (1 << 2));
580360SN/A
581360SN/A    //Turn on red and hpriv, set everything else to 0
582360SN/A    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
5836640Svince@csl.cornell.edu    //HPSTATE.red = 1
5846640Svince@csl.cornell.edu    HPSTATE |= (1 << 5);
5856640Svince@csl.cornell.edu    //HPSTATE.hpriv = 1
5866640Svince@csl.cornell.edu    HPSTATE |= (1 << 2);
5876640Svince@csl.cornell.edu    //HPSTATE.ibe = 0
5886640Svince@csl.cornell.edu    HPSTATE &= ~(1 << 10);
5896640Svince@csl.cornell.edu    //HPSTATE.tlz = 0
5906701Sgblack@eecs.umich.edu    HPSTATE &= ~(1 << 0);
5916701Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
5926701Sgblack@eecs.umich.edu
5936640Svince@csl.cornell.edu    //The tick register is unreadable by nonprivileged software
5946701Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TICK, 1ULL << 63);
5956701Sgblack@eecs.umich.edu
5966640Svince@csl.cornell.edu    //Enter RED state. We do this last so that the actual state preserved in
5978706Sandreas.hansson@arm.com    //the trap stack is the state from before this fault.
5986640Svince@csl.cornell.edu    enterREDState(tc);
5996701Sgblack@eecs.umich.edu
6006640Svince@csl.cornell.edu    Addr PC, NPC;
601360SN/A    getREDVector(trapType(), PC, NPC);
6021999SN/A    tc->setPC(PC);
6031999SN/A    tc->setNextPC(NPC);
6041999SN/A    tc->setNextNPC(NPC + sizeof(MachInst));
6053114Sgblack@eecs.umich.edu
6062680Sktlim@umich.edu    //These registers are specified as "undefined" after a POR, and they
6071999SN/A    //should have reasonable values after the miscregfile is reset
6081999SN/A    /*
6091999SN/A    // Clear all the soft interrupt bits
6106701Sgblack@eecs.umich.edu    softint = 0;
6118852Sandreas.hansson@arm.com    // disable timer compare interrupts, reset tick_cmpr
6126701Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_
6131999SN/A    tick_cmprFields.int_dis = 1;
6146701Sgblack@eecs.umich.edu    tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6151999SN/A    stickFields.npt = 1; //The TICK register is unreadable by by !priv
6166701Sgblack@eecs.umich.edu    stick_cmprFields.int_dis = 1; // disable timer compare interrupts
6171999SN/A    stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6181999SN/A
6191999SN/A    tt[tl] = _trapType;
6201999SN/A
6211999SN/A    hintp = 0; // no interrupts pending
6223669Sbinkertn@umich.edu    hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
6233669Sbinkertn@umich.edu    hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6243669Sbinkertn@umich.edu    */
6251999SN/A}
6261999SN/A
6271999SN/A#else // !FULL_SYSTEM
6282218SN/A
6291999SN/Avoid SpillNNormal::invoke(ThreadContext *tc)
6301999SN/A{
6311999SN/A    doNormalFault(tc, trapType(), false);
6321999SN/A
6331999SN/A    Process *p = tc->getProcessPtr();
6341999SN/A
6351999SN/A    //XXX This will only work in faults from a SparcLiveProcess
6361999SN/A    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
6373114Sgblack@eecs.umich.edu    assert(lp);
6382680Sktlim@umich.edu
6391999SN/A    //Then adjust the PC and NPC
6406701Sgblack@eecs.umich.edu    Addr spillStart = lp->readSpillStart();
6416701Sgblack@eecs.umich.edu    tc->setPC(spillStart);
6421999SN/A    tc->setNextPC(spillStart + sizeof(MachInst));
6431999SN/A    tc->setNextNPC(spillStart + 2*sizeof(MachInst));
6441999SN/A}
6451999SN/A
6461999SN/Avoid FillNNormal::invoke(ThreadContext *tc)
6476701Sgblack@eecs.umich.edu{
6481999SN/A    doNormalFault(tc, trapType(), false);
6491999SN/A
6501999SN/A    Process * p = tc->getProcessPtr();
6511999SN/A
6521999SN/A    //XXX This will only work in faults from a SparcLiveProcess
6531999SN/A    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
6541999SN/A    assert(lp);
6551999SN/A
6562218SN/A    //Then adjust the PC and NPC
6571999SN/A    Addr fillStart = lp->readFillStart();
6581999SN/A    tc->setPC(fillStart);
6591999SN/A    tc->setNextPC(fillStart + sizeof(MachInst));
6601999SN/A    tc->setNextNPC(fillStart + 2*sizeof(MachInst));
6615877Shsul@eecs.umich.edu}
6625877Shsul@eecs.umich.edu
6635877Shsul@eecs.umich.eduvoid PageTableFault::invoke(ThreadContext *tc)
6645877Shsul@eecs.umich.edu{
6655877Shsul@eecs.umich.edu    Process *p = tc->getProcessPtr();
6666701Sgblack@eecs.umich.edu
6676701Sgblack@eecs.umich.edu    // We've accessed the next page of the stack, so extend the stack
6686701Sgblack@eecs.umich.edu    // to cover it.
6696701Sgblack@eecs.umich.edu    if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes)
6706701Sgblack@eecs.umich.edu    {
6715877Shsul@eecs.umich.edu        p->stack_min -= PageBytes;
6725877Shsul@eecs.umich.edu        if(p->stack_base - p->stack_min > 8*1024*1024)
6735877Shsul@eecs.umich.edu            fatal("Over max stack size for one thread\n");
6745877Shsul@eecs.umich.edu        p->pTable->allocate(p->stack_min, PageBytes);
6755877Shsul@eecs.umich.edu        warn("Increasing stack size by one page.");
6765877Shsul@eecs.umich.edu    }
6775877Shsul@eecs.umich.edu    // Otherwise, we have an unexpected page fault. Report that fact,
6785877Shsul@eecs.umich.edu    // and what address was accessed to cause the fault.
6795877Shsul@eecs.umich.edu    else
6805877Shsul@eecs.umich.edu    {
6818601Ssteve.reinhardt@amd.com        panic("Page table fault when accessing virtual address %#x\n", vaddr);
6825877Shsul@eecs.umich.edu    }
6835877Shsul@eecs.umich.edu}
6845877Shsul@eecs.umich.edu
6855877Shsul@eecs.umich.edu#endif
6865877Shsul@eecs.umich.edu
6875877Shsul@eecs.umich.edu} // namespace SparcISA
6885877Shsul@eecs.umich.edu
6895877Shsul@eecs.umich.edu