faults.cc revision 7741
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/**
2716703Svince@csl.cornell.edu * This causes the thread context to enter RED state. This causes the side
2726703Svince@csl.cornell.edu * effects which go with entering RED state because of a trap.
2736703Svince@csl.cornell.edu */
2746685Stjones1@inf.ed.ac.uk
2756685Stjones1@inf.ed.ac.ukvoid
2766685Stjones1@inf.ed.ac.ukenterREDState(ThreadContext *tc)
2776685Stjones1@inf.ed.ac.uk{
2786685Stjones1@inf.ed.ac.uk    //@todo Disable the mmu?
2795513SMichael.Adler@intel.com    //@todo Disable watchpoints?
2805513SMichael.Adler@intel.com    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
2815513SMichael.Adler@intel.com    // HPSTATE.red = 1
2825513SMichael.Adler@intel.com    HPSTATE |= (1 << 5);
2835513SMichael.Adler@intel.com    // HPSTATE.hpriv = 1
2841999SN/A    HPSTATE |= (1 << 2);
2851999SN/A    tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
2863114Sgblack@eecs.umich.edu    // PSTATE.priv is set to 1 here. The manual says it should be 0, but
2871999SN/A    // Legion sets it to 1.
2881999SN/A    MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
2891999SN/A    PSTATE |= (1 << 2);
2901999SN/A    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
2913114Sgblack@eecs.umich.edu}
2921999SN/A
2933079Sstever@eecs.umich.edu/**
2943079Sstever@eecs.umich.edu * This sets everything up for a RED state trap except for actually jumping to
2953114Sgblack@eecs.umich.edu * the handler.
2963079Sstever@eecs.umich.edu */
2972093SN/A
2982093SN/Avoid
2993114Sgblack@eecs.umich.edudoREDFault(ThreadContext *tc, TrapType tt)
3002093SN/A{
3012687Sksewell@umich.edu    MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
3022687Sksewell@umich.edu    MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
3033114Sgblack@eecs.umich.edu    MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
3042687Sksewell@umich.edu    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
3052238SN/A    MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
3062238SN/A    MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
3073114Sgblack@eecs.umich.edu    MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
3082238SN/A    MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
3092238SN/A    MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
3102238SN/A    PCState pc = tc->pcState();
3113114Sgblack@eecs.umich.edu
3122238SN/A    TL++;
3132238SN/A
3142238SN/A    Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
3153114Sgblack@eecs.umich.edu
3162238SN/A    // set TSTATE.gl to gl
3172238SN/A    replaceBits(TSTATE, 42, 40, GL);
3182238SN/A    // set TSTATE.ccr to ccr
3193114Sgblack@eecs.umich.edu    replaceBits(TSTATE, 39, 32, CCR);
3202238SN/A    // set TSTATE.asi to asi
3212238SN/A    replaceBits(TSTATE, 31, 24, ASI);
3222238SN/A    // set TSTATE.pstate to pstate
3233114Sgblack@eecs.umich.edu    replaceBits(TSTATE, 20, 8, PSTATE);
3242238SN/A    // set TSTATE.cwp to cwp
3252238SN/A    replaceBits(TSTATE, 4, 0, CWP);
3262238SN/A
3273114Sgblack@eecs.umich.edu    // Write back TSTATE
3282238SN/A    tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
3292238SN/A
3302238SN/A    // set TPC to PC
3313114Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
3322238SN/A    // set TNPC to NPC
3336109Ssanchezd@stanford.edu    tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
3346109Ssanchezd@stanford.edu
3356109Ssanchezd@stanford.edu    // set HTSTATE.hpstate to hpstate
3362238SN/A    tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
3372238SN/A
3382238SN/A    // TT = trap type;
3392238SN/A    tc->setMiscRegNoEffect(MISCREG_TT, tt);
3402238SN/A
3413114Sgblack@eecs.umich.edu    // Update GL
3422238SN/A    tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
3432238SN/A
3442238SN/A    PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
3453114Sgblack@eecs.umich.edu    PSTATE |= (1 << 4); // set PSTATE.pef to 1
3462238SN/A    tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
3472238SN/A
3482238SN/A    // set HPSTATE.red to 1
3493114Sgblack@eecs.umich.edu    HPSTATE |= (1 << 5);
3502238SN/A    // set HPSTATE.hpriv to 1
3512238SN/A    HPSTATE |= (1 << 2);
3522238SN/A    // set HPSTATE.ibe to 0
3533114Sgblack@eecs.umich.edu    HPSTATE &= ~(1 << 10);
3542238SN/A    // set HPSTATE.tlz to 0
3552238SN/A    HPSTATE &= ~(1 << 0);
3561354SN/A    tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
3571354SN/A
3581354SN/A    bool changedCWP = true;
3591354SN/A    if (tt == 0x24)
3601354SN/A        CWP++;
3611354SN/A    else if (0x80 <= tt && tt <= 0xbf)
3621354SN/A        CWP += (CANSAVE + 2);
3631354SN/A    else if (0xc0 <= tt && tt <= 0xff)
3641354SN/A        CWP--;
3651354SN/A    else
3661354SN/A        changedCWP = false;
3671354SN/A
3681354SN/A    if (changedCWP) {
3691354SN/A        CWP = (CWP + NWindows) % NWindows;
3707823Ssteve.reinhardt@amd.com        tc->setMiscReg(MISCREG_CWP, CWP);
3711354SN/A    }
3721354SN/A}
3731354SN/A
3741354SN/A/**
375360SN/A * This sets everything up for a normal trap except for actually jumping to
376360SN/A * the handler.
377360SN/A */
378360SN/A
379360SN/Avoid
380360SN/AdoNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
381360SN/A{
3823113Sgblack@eecs.umich.edu    MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
3833113Sgblack@eecs.umich.edu    MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
3843113Sgblack@eecs.umich.edu    MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE);
3853113Sgblack@eecs.umich.edu    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
3863113Sgblack@eecs.umich.edu    MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
3873113Sgblack@eecs.umich.edu    MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
3883113Sgblack@eecs.umich.edu    MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
3893113Sgblack@eecs.umich.edu    MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
3903113Sgblack@eecs.umich.edu    MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
3913113Sgblack@eecs.umich.edu    PCState pc = tc->pcState();
3923113Sgblack@eecs.umich.edu
3933113Sgblack@eecs.umich.edu    // Increment the trap level
3943113Sgblack@eecs.umich.edu    TL++;
3953113Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_TL, TL);
3963113Sgblack@eecs.umich.edu
3973113Sgblack@eecs.umich.edu    Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64);
3984189Sgblack@eecs.umich.edu
3994189Sgblack@eecs.umich.edu    // Save off state
4003113Sgblack@eecs.umich.edu
4013113Sgblack@eecs.umich.edu    // set TSTATE.gl to gl
4023113Sgblack@eecs.umich.edu    replaceBits(TSTATE, 42, 40, GL);
4033113Sgblack@eecs.umich.edu    // set TSTATE.ccr to ccr
4048737Skoansin.tan@gmail.com    replaceBits(TSTATE, 39, 32, CCR);
4053113Sgblack@eecs.umich.edu    // set TSTATE.asi to asi
4068737Skoansin.tan@gmail.com    replaceBits(TSTATE, 31, 24, ASI);
4073277Sgblack@eecs.umich.edu    // set TSTATE.pstate to pstate
4085515SMichael.Adler@intel.com    replaceBits(TSTATE, 20, 8, PSTATE);
4095515SMichael.Adler@intel.com    // set TSTATE.cwp to cwp
4105515SMichael.Adler@intel.com    replaceBits(TSTATE, 4, 0, CWP);
4115515SMichael.Adler@intel.com
4125515SMichael.Adler@intel.com    // Write back TSTATE
4138737Skoansin.tan@gmail.com    tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
4143277Sgblack@eecs.umich.edu
4158737Skoansin.tan@gmail.com    // set TPC to PC
4163277Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
4178737Skoansin.tan@gmail.com    // set TNPC to NPC
4183277Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
4198737Skoansin.tan@gmail.com
4203113Sgblack@eecs.umich.edu    // set HTSTATE.hpstate to hpstate
4213113Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE);
4223113Sgblack@eecs.umich.edu
4233113Sgblack@eecs.umich.edu    // TT = trap type;
4248737Skoansin.tan@gmail.com    tc->setMiscRegNoEffect(MISCREG_TT, tt);
4253113Sgblack@eecs.umich.edu
4268737Skoansin.tan@gmail.com    // Update the global register level
4273114Sgblack@eecs.umich.edu    if (!gotoHpriv)
4288737Skoansin.tan@gmail.com        tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxPGL));
4293114Sgblack@eecs.umich.edu    else
4308737Skoansin.tan@gmail.com        tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL));
4313114Sgblack@eecs.umich.edu
4328737Skoansin.tan@gmail.com    // PSTATE.mm is unchanged
4334061Sgblack@eecs.umich.edu    PSTATE |= (1 << 4); // PSTATE.pef = whether or not an fpu is present
4344061Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 3); // PSTATE.am = 0
4354061Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 1); // PSTATE.ie = 0
4368737Skoansin.tan@gmail.com    // PSTATE.tle is unchanged
4373113Sgblack@eecs.umich.edu    // PSTATE.tct = 0
4388737Skoansin.tan@gmail.com
4393113Sgblack@eecs.umich.edu    if (gotoHpriv) {
4403113Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 9); // PSTATE.cle = 0
4413113Sgblack@eecs.umich.edu        // The manual says PSTATE.priv should be 0, but Legion leaves it alone
4423113Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 5); // HPSTATE.red = 0
4433113Sgblack@eecs.umich.edu        HPSTATE |= (1 << 2); // HPSTATE.hpriv = 1
4443113Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 10); // HPSTATE.ibe = 0
4453113Sgblack@eecs.umich.edu        // HPSTATE.tlz is unchanged
4463113Sgblack@eecs.umich.edu        tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
4474189Sgblack@eecs.umich.edu    } else { // we are going to priv
4484189Sgblack@eecs.umich.edu        PSTATE |= (1 << 2); // PSTATE.priv = 1
4493113Sgblack@eecs.umich.edu        replaceBits(PSTATE, 9, 9, PSTATE >> 8); // PSTATE.cle = PSTATE.tle
4503113Sgblack@eecs.umich.edu    }
4513113Sgblack@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE);
4528737Skoansin.tan@gmail.com
4533113Sgblack@eecs.umich.edu
4548737Skoansin.tan@gmail.com    bool changedCWP = true;
4553113Sgblack@eecs.umich.edu    if (tt == 0x24)
4568737Skoansin.tan@gmail.com        CWP++;
4573113Sgblack@eecs.umich.edu    else if (0x80 <= tt && tt <= 0xbf)
4583113Sgblack@eecs.umich.edu        CWP += (CANSAVE + 2);
4593113Sgblack@eecs.umich.edu    else if (0xc0 <= tt && tt <= 0xff)
4603113Sgblack@eecs.umich.edu        CWP--;
4613113Sgblack@eecs.umich.edu    else
4623113Sgblack@eecs.umich.edu        changedCWP = false;
4633113Sgblack@eecs.umich.edu
4643113Sgblack@eecs.umich.edu    if (changedCWP) {
4653113Sgblack@eecs.umich.edu        CWP = (CWP + NWindows) % NWindows;
4663113Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_CWP, CWP);
4678852Sandreas.hansson@arm.com    }
4683113Sgblack@eecs.umich.edu}
4693113Sgblack@eecs.umich.edu
4703113Sgblack@eecs.umich.eduvoid
4713113Sgblack@eecs.umich.edugetREDVector(MiscReg TT, Addr &PC, Addr &NPC)
4723113Sgblack@eecs.umich.edu{
4733113Sgblack@eecs.umich.edu    //XXX The following constant might belong in a header file.
4743113Sgblack@eecs.umich.edu    const Addr RSTVAddr = 0xFFF0000000ULL;
4753113Sgblack@eecs.umich.edu    PC = RSTVAddr | ((TT << 5) & 0xFF);
4763113Sgblack@eecs.umich.edu    NPC = PC + sizeof(MachInst);
4773113Sgblack@eecs.umich.edu}
4788852Sandreas.hansson@arm.com
4793113Sgblack@eecs.umich.eduvoid
4803113Sgblack@eecs.umich.edugetHyperVector(ThreadContext * tc, Addr &PC, Addr &NPC, MiscReg TT)
4813113Sgblack@eecs.umich.edu{
4823113Sgblack@eecs.umich.edu    Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA);
4836686Stjones1@inf.ed.ac.uk    PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
4843113Sgblack@eecs.umich.edu    NPC = PC + sizeof(MachInst);
4853113Sgblack@eecs.umich.edu}
4863113Sgblack@eecs.umich.edu
487378SN/Avoid
488378SN/AgetPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, MiscReg TT, MiscReg TL)
489378SN/A{
490360SN/A    Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA);
4911450SN/A    PC = (TBA & ~mask(15)) |
4923114Sgblack@eecs.umich.edu        (TL > 1 ? (1 << 14) : 0) |
4932680Sktlim@umich.edu        ((TT << 5) & mask(14));
494360SN/A    NPC = PC + sizeof(MachInst);
4956701Sgblack@eecs.umich.edu}
4966701Sgblack@eecs.umich.edu
4976701Sgblack@eecs.umich.edu#if FULL_SYSTEM
498360SN/A
4991969SN/Avoid
500360SN/ASparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
501360SN/A{
502360SN/A    FaultBase::invoke(tc);
5031458SN/A    countStat()++;
504360SN/A
505360SN/A    // We can refer to this to see what the trap level -was-, but something
506360SN/A    // in the middle could change it in the regfile out from under us.
5074131Sbinkertn@umich.edu    MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL);
5084131Sbinkertn@umich.edu    MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT);
5094131Sbinkertn@umich.edu    MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
5104131Sbinkertn@umich.edu    MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
5114131Sbinkertn@umich.edu
5124131Sbinkertn@umich.edu    Addr PC, NPC;
5134131Sbinkertn@umich.edu
5144131Sbinkertn@umich.edu    PrivilegeLevel current;
5156689Stjones1@inf.ed.ac.uk    if (hpstate & HPSTATE::hpriv)
5161458SN/A        current = Hyperprivileged;
517360SN/A    else if (pstate & PSTATE::priv)
518360SN/A        current = Privileged;
5197720Sgblack@eecs.umich.edu    else
5207720Sgblack@eecs.umich.edu        current = User;
521360SN/A
522360SN/A    PrivilegeLevel level = getNextLevel(current);
523360SN/A
524378SN/A    if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) {
525360SN/A        getREDVector(5, PC, NPC);
5261450SN/A        doREDFault(tc, tt);
5273114Sgblack@eecs.umich.edu        // This changes the hpstate and pstate, so we need to make sure we
5282680Sktlim@umich.edu        // save the old version on the trap stack in doREDFault.
529360SN/A        enterREDState(tc);
530360SN/A    } else if (tl == MaxTL) {
531360SN/A        panic("Should go to error state here.. crap\n");
5326701Sgblack@eecs.umich.edu        // Do error_state somehow?
5338852Sandreas.hansson@arm.com        // Probably inject a WDR fault using the interrupt mechanism.
5346701Sgblack@eecs.umich.edu        // What should the PC and NPC be set to?
5351458SN/A    } else if (tl > MaxPTL && level == Privileged) {
536360SN/A        // guest_watchdog fault
537360SN/A        doNormalFault(tc, trapType(), true);
538360SN/A        getHyperVector(tc, PC, NPC, 2);
539360SN/A    } else if (level == Hyperprivileged ||
5401706SN/A               (level == Privileged && trapType() >= 384)) {
5411458SN/A        doNormalFault(tc, trapType(), true);
542360SN/A        getHyperVector(tc, PC, NPC, trapType());
543360SN/A    } else {
5446701Sgblack@eecs.umich.edu        doNormalFault(tc, trapType(), false);
5456701Sgblack@eecs.umich.edu        getPrivVector(tc, PC, NPC, trapType(), tl + 1);
546360SN/A    }
547360SN/A
548360SN/A    PCState pc;
549360SN/A    pc.pc(PC);
550360SN/A    pc.npc(NPC);
551360SN/A    pc.nnpc(NPC + sizeof(MachInst));
552360SN/A    pc.upc(0);
553360SN/A    pc.nupc(1);
554360SN/A    tc->pcState(pc);
555360SN/A}
556360SN/A
557360SN/Avoid
5581706SN/APowerOnReset::invoke(ThreadContext *tc, StaticInstPtr inst)
559360SN/A{
560360SN/A    // For SPARC, when a system is first started, there is a power
561360SN/A    // on reset Trap which sets the processor into the following state.
562360SN/A    // Bits that aren't set aren't defined on startup.
563360SN/A
5643669Sbinkertn@umich.edu    tc->setMiscRegNoEffect(MISCREG_TL, MaxTL);
5653669Sbinkertn@umich.edu    tc->setMiscRegNoEffect(MISCREG_TT, trapType());
5663669Sbinkertn@umich.edu    tc->setMiscReg(MISCREG_GL, MaxGL);
5671706SN/A
5681706SN/A    // Turn on pef and priv, set everything else to 0
5695795Ssaidi@eecs.umich.edu    tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2));
5705795Ssaidi@eecs.umich.edu
5715795Ssaidi@eecs.umich.edu    // Turn on red and hpriv, set everything else to 0
5725795Ssaidi@eecs.umich.edu    MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
5735795Ssaidi@eecs.umich.edu    // HPSTATE.red = 1
5745795Ssaidi@eecs.umich.edu    HPSTATE |= (1 << 5);
5755795Ssaidi@eecs.umich.edu    // HPSTATE.hpriv = 1
5765795Ssaidi@eecs.umich.edu    HPSTATE |= (1 << 2);
5775795Ssaidi@eecs.umich.edu    // HPSTATE.ibe = 0
5785795Ssaidi@eecs.umich.edu    HPSTATE &= ~(1 << 10);
5795795Ssaidi@eecs.umich.edu    // HPSTATE.tlz = 0
580360SN/A    HPSTATE &= ~(1 << 0);
581360SN/A    tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE);
582360SN/A
5836640Svince@csl.cornell.edu    // The tick register is unreadable by nonprivileged software
5846640Svince@csl.cornell.edu    tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
5856640Svince@csl.cornell.edu
5866640Svince@csl.cornell.edu    // Enter RED state. We do this last so that the actual state preserved in
5876640Svince@csl.cornell.edu    // the trap stack is the state from before this fault.
5886640Svince@csl.cornell.edu    enterREDState(tc);
5896640Svince@csl.cornell.edu
5906701Sgblack@eecs.umich.edu    Addr PC, NPC;
5916701Sgblack@eecs.umich.edu    getREDVector(trapType(), PC, NPC);
5926701Sgblack@eecs.umich.edu
5936640Svince@csl.cornell.edu    PCState pc;
5946701Sgblack@eecs.umich.edu    pc.pc(PC);
5956701Sgblack@eecs.umich.edu    pc.npc(NPC);
5966640Svince@csl.cornell.edu    pc.nnpc(NPC + sizeof(MachInst));
5978706Sandreas.hansson@arm.com    pc.upc(0);
5986640Svince@csl.cornell.edu    pc.nupc(1);
5996701Sgblack@eecs.umich.edu    tc->pcState(pc);
6006640Svince@csl.cornell.edu
601360SN/A    // These registers are specified as "undefined" after a POR, and they
6021999SN/A    // should have reasonable values after the miscregfile is reset
6031999SN/A    /*
6041999SN/A    // Clear all the soft interrupt bits
6053114Sgblack@eecs.umich.edu    softint = 0;
6062680Sktlim@umich.edu    // disable timer compare interrupts, reset tick_cmpr
6071999SN/A    tc->setMiscRegNoEffect(MISCREG_
6081999SN/A    tick_cmprFields.int_dis = 1;
6091999SN/A    tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6106701Sgblack@eecs.umich.edu    stickFields.npt = 1; // The TICK register is unreadable by by !priv
6118852Sandreas.hansson@arm.com    stick_cmprFields.int_dis = 1; // disable timer compare interrupts
6126701Sgblack@eecs.umich.edu    stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6131999SN/A
6146701Sgblack@eecs.umich.edu    tt[tl] = _trapType;
6151999SN/A
6166701Sgblack@eecs.umich.edu    hintp = 0; // no interrupts pending
6171999SN/A    hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
6181999SN/A    hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6191999SN/A    */
6201999SN/A}
6211999SN/A
6223669Sbinkertn@umich.edu#else // !FULL_SYSTEM
6233669Sbinkertn@umich.edu
6243669Sbinkertn@umich.eduvoid
6251999SN/AFastInstructionAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
6261999SN/A{
6271999SN/A    Process *p = tc->getProcessPtr();
6282218SN/A    TlbEntry entry;
6291999SN/A    bool success = p->pTable->lookup(vaddr, entry);
6301999SN/A    if (!success) {
6311999SN/A        panic("Tried to execute unmapped address %#x.\n", vaddr);
6321999SN/A    } else {
6331999SN/A        Addr alignedVaddr = p->pTable->pageAlign(vaddr);
6341999SN/A        tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/,
6351999SN/A                p->M5_pid /*context id*/, false, entry.pte);
6361999SN/A    }
6373114Sgblack@eecs.umich.edu}
6382680Sktlim@umich.edu
6391999SN/Avoid
6406701Sgblack@eecs.umich.eduFastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
6416701Sgblack@eecs.umich.edu{
6421999SN/A    Process *p = tc->getProcessPtr();
6431999SN/A    TlbEntry entry;
6441999SN/A    bool success = p->pTable->lookup(vaddr, entry);
6451999SN/A    if (!success) {
6461999SN/A        p->checkAndAllocNextPage(vaddr);
6476701Sgblack@eecs.umich.edu        success = p->pTable->lookup(vaddr, entry);
6481999SN/A    }
6491999SN/A    if (!success) {
6501999SN/A        panic("Tried to access unmapped address %#x.\n", vaddr);
6511999SN/A    } else {
6521999SN/A        Addr alignedVaddr = p->pTable->pageAlign(vaddr);
6531999SN/A        tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/,
6541999SN/A                p->M5_pid /*context id*/, false, entry.pte);
6551999SN/A    }
6562218SN/A}
6571999SN/A
6581999SN/Avoid
6591999SN/ASpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
6601999SN/A{
6615877Shsul@eecs.umich.edu    doNormalFault(tc, trapType(), false);
6625877Shsul@eecs.umich.edu
6635877Shsul@eecs.umich.edu    Process *p = tc->getProcessPtr();
6645877Shsul@eecs.umich.edu
6655877Shsul@eecs.umich.edu    //XXX This will only work in faults from a SparcLiveProcess
6666701Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
6676701Sgblack@eecs.umich.edu    assert(lp);
6686701Sgblack@eecs.umich.edu
6696701Sgblack@eecs.umich.edu    // Then adjust the PC and NPC
6706701Sgblack@eecs.umich.edu    tc->pcState(lp->readSpillStart());
6715877Shsul@eecs.umich.edu}
6725877Shsul@eecs.umich.edu
6735877Shsul@eecs.umich.eduvoid
6745877Shsul@eecs.umich.eduFillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
6755877Shsul@eecs.umich.edu{
6765877Shsul@eecs.umich.edu    doNormalFault(tc, trapType(), false);
6775877Shsul@eecs.umich.edu
6785877Shsul@eecs.umich.edu    Process *p = tc->getProcessPtr();
6795877Shsul@eecs.umich.edu
6805877Shsul@eecs.umich.edu    //XXX This will only work in faults from a SparcLiveProcess
6818601Ssteve.reinhardt@amd.com    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
6825877Shsul@eecs.umich.edu    assert(lp);
6835877Shsul@eecs.umich.edu
6845877Shsul@eecs.umich.edu    // Then adjust the PC and NPC
6855877Shsul@eecs.umich.edu    tc->pcState(lp->readFillStart());
6865877Shsul@eecs.umich.edu}
6875877Shsul@eecs.umich.edu
6885877Shsul@eecs.umich.eduvoid
6895877Shsul@eecs.umich.eduTrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
6905877Shsul@eecs.umich.edu{
6915877Shsul@eecs.umich.edu    // In SE, this mechanism is how the process requests a service from the
6925877Shsul@eecs.umich.edu    // operating system. We'll get the process object from the thread context
6935877Shsul@eecs.umich.edu    // and let it service the request.
6945877Shsul@eecs.umich.edu
6958601Ssteve.reinhardt@amd.com    Process *p = tc->getProcessPtr();
6968601Ssteve.reinhardt@amd.com
6975877Shsul@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
6985877Shsul@eecs.umich.edu    assert(lp);
6995877Shsul@eecs.umich.edu
7005877Shsul@eecs.umich.edu    lp->handleTrap(_n, tc);
7015877Shsul@eecs.umich.edu
7025877Shsul@eecs.umich.edu    // We need to explicitly advance the pc, since that's not done for us
7038601Ssteve.reinhardt@amd.com    // on a faulting instruction
7045877Shsul@eecs.umich.edu    PCState pc = tc->pcState();
7055877Shsul@eecs.umich.edu    pc.advance();
7065877Shsul@eecs.umich.edu    tc->pcState(pc);
7071999SN/A}
708378SN/A
709360SN/A#endif
7101450SN/A
7113114Sgblack@eecs.umich.edu} // namespace SparcISA
7122680Sktlim@umich.edu
713360SN/A