faults.cc revision 3825
1360SN/A/*
210850SGiacomo.Gabrielli@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
310796Sbrandon.potter@amd.com * All rights reserved.
410027SChris.Adeniyi-Jones@arm.com *
510027SChris.Adeniyi-Jones@arm.com * Redistribution and use in source and binary forms, with or without
610027SChris.Adeniyi-Jones@arm.com * modification, are permitted provided that the following conditions are
710027SChris.Adeniyi-Jones@arm.com * met: redistributions of source code must retain the above copyright
810027SChris.Adeniyi-Jones@arm.com * notice, this list of conditions and the following disclaimer;
910027SChris.Adeniyi-Jones@arm.com * redistributions in binary form must reproduce the above copyright
1010027SChris.Adeniyi-Jones@arm.com * notice, this list of conditions and the following disclaimer in the
1110027SChris.Adeniyi-Jones@arm.com * documentation and/or other materials provided with the distribution;
1210027SChris.Adeniyi-Jones@arm.com * neither the name of the copyright holders nor the names of its
1310027SChris.Adeniyi-Jones@arm.com * contributors may be used to endorse or promote products derived from
1410027SChris.Adeniyi-Jones@arm.com * this software without specific prior written permission.
151458SN/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.
27360SN/A *
28360SN/A * Authors: Gabe Black
29360SN/A *          Kevin Lim
30360SN/A */
31360SN/A
32360SN/A#include <algorithm>
33360SN/A
34360SN/A#include "arch/sparc/faults.hh"
35360SN/A#include "arch/sparc/isa_traits.hh"
36360SN/A#include "arch/sparc/types.hh"
37360SN/A#include "base/bitfield.hh"
38360SN/A#include "base/trace.hh"
39360SN/A#include "config/full_system.hh"
402665Ssaidi@eecs.umich.edu#include "cpu/base.hh"
412665Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh"
422665Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
43360SN/A#include "arch/sparc/process.hh"
44360SN/A#include "mem/page_table.hh"
451354SN/A#include "sim/process.hh"
461354SN/A#endif
47360SN/A
4812018Sandreas.sandberg@arm.comusing namespace std;
4912018Sandreas.sandberg@arm.com
5012018Sandreas.sandberg@arm.comnamespace SparcISA
5112018Sandreas.sandberg@arm.com{
5212018Sandreas.sandberg@arm.com
5312018Sandreas.sandberg@arm.comtemplate<> SparcFaultBase::FaultVals
5412018Sandreas.sandberg@arm.com    SparcFault<PowerOnReset>::vals =
552064SN/A    {"power_on_reset", 0x001, 0, {H, H, H}};
5612018Sandreas.sandberg@arm.com
5712018Sandreas.sandberg@arm.comtemplate<> SparcFaultBase::FaultVals
5812018Sandreas.sandberg@arm.com    SparcFault<WatchDogReset>::vals =
5912018Sandreas.sandberg@arm.com    {"watch_dog_reset", 0x002, 120, {H, H, H}};
6012018Sandreas.sandberg@arm.com
6112018Sandreas.sandberg@arm.comtemplate<> SparcFaultBase::FaultVals
6211799Sbrandon.potter@amd.com    SparcFault<ExternallyInitiatedReset>::vals =
6312018Sandreas.sandberg@arm.com    {"externally_initiated_reset", 0x003, 110, {H, H, H}};
6412018Sandreas.sandberg@arm.com
6512018Sandreas.sandberg@arm.comtemplate<> SparcFaultBase::FaultVals
6612018Sandreas.sandberg@arm.com    SparcFault<SoftwareInitiatedReset>::vals =
6712018Sandreas.sandberg@arm.com    {"software_initiated_reset", 0x004, 130, {SH, SH, H}};
6812018Sandreas.sandberg@arm.com
6911799Sbrandon.potter@amd.comtemplate<> 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}};
761809SN/A
7711800Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
7811392Sbrandon.potter@amd.com    SparcFault<InstructionAccessException>::vals =
791809SN/A    {"instruction_access_exception", 0x008, 300, {H, H, H}};
8011392Sbrandon.potter@amd.com
8113570Sbrandon.potter@amd.com//XXX This trap is apparently dropped from ua2005
8211383Sbrandon.potter@amd.com/*template<> SparcFaultBase::FaultVals
8313568Sbrandon.potter@amd.com    SparcFault<InstructionAccessMMUMiss>::vals =
843113Sgblack@eecs.umich.edu    {"inst_mmu", 0x009, 2, {H, H, H}};*/
8511799Sbrandon.potter@amd.com
8611759Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
8711812Sbaz21@cam.ac.uk    SparcFault<InstructionAccessError>::vals =
8811812Sbaz21@cam.ac.uk    {"instruction_access_error", 0x00A, 400, {H, H, H}};
8911799Sbrandon.potter@amd.com
908229Snate@binkert.orgtemplate<> SparcFaultBase::FaultVals
9113570Sbrandon.potter@amd.com    SparcFault<IllegalInstruction>::vals =
928229Snate@binkert.org    {"illegal_instruction", 0x010, 620, {H, H, H}};
9311594Santhony.gutierrez@amd.com
947075Snate@binkert.orgtemplate<> SparcFaultBase::FaultVals
958229Snate@binkert.org    SparcFault<PrivilegedOpcode>::vals =
9611856Sbrandon.potter@amd.com    {"privileged_opcode", 0x011, 700, {P, SH, SH}};
977075Snate@binkert.org
98360SN/A//XXX This trap is apparently dropped from ua2005
9912461Sgabeblack@google.com/*template<> SparcFaultBase::FaultVals
10011886Sbrandon.potter@amd.com    SparcFault<UnimplementedLDD>::vals =
10111800Sbrandon.potter@amd.com    {"unimp_ldd", 0x012, 6, {H, H, H}};*/
10211392Sbrandon.potter@amd.com
10312334Sgabeblack@google.com//XXX This trap is apparently dropped from ua2005
1041354SN/A/*template<> SparcFaultBase::FaultVals
1056216Snate@binkert.org    SparcFault<UnimplementedSTD>::vals =
1066658Snate@binkert.org    {"unimp_std", 0x013, 6, {H, H, H}};*/
1072474SN/A
1082680Sktlim@umich.edutemplate<> SparcFaultBase::FaultVals
1098229Snate@binkert.org    SparcFault<FpDisabled>::vals =
11011886Sbrandon.potter@amd.com    {"fp_disabled", 0x020, 800, {P, P, H}};
11110496Ssteve.reinhardt@amd.com
11211911SBrandon.Potter@amd.comtemplate<> SparcFaultBase::FaultVals
1138229Snate@binkert.org    SparcFault<FpExceptionIEEE754>::vals =
11411794Sbrandon.potter@amd.com    {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}};
11511886Sbrandon.potter@amd.com
11610497Ssteve.reinhardt@amd.comtemplate<> SparcFaultBase::FaultVals
11711794Sbrandon.potter@amd.com    SparcFault<FpExceptionOther>::vals =
118360SN/A    {"fp_exception_other", 0x022, 1110, {P, P, H}};
11913629SAndrea.Mondelli@ucf.edu
12013629SAndrea.Mondelli@ucf.edutemplate<> SparcFaultBase::FaultVals
12113629SAndrea.Mondelli@ucf.edu    SparcFault<TagOverflow>::vals =
12213629SAndrea.Mondelli@ucf.edu    {"tag_overflow", 0x023, 1400, {P, P, H}};
123360SN/A
124360SN/Atemplate<> SparcFaultBase::FaultVals
125360SN/A    SparcFault<CleanWindow>::vals =
126360SN/A    {"clean_window", 0x024, 1010, {P, P, H}};
127360SN/A
128360SN/Atemplate<> SparcFaultBase::FaultVals
129360SN/A    SparcFault<DivisionByZero>::vals =
130360SN/A    {"division_by_zero", 0x028, 1500, {P, P, H}};
131360SN/A
132378SN/Atemplate<> SparcFaultBase::FaultVals
1331706SN/A    SparcFault<InternalProcessorError>::vals =
13411851Sbrandon.potter@amd.com    {"internal_processor_error", 0x029, 4, {H, H, H}};
135378SN/A
136378SN/Atemplate<> SparcFaultBase::FaultVals
137378SN/A    SparcFault<InstructionInvalidTSBEntry>::vals =
138378SN/A    {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}};
139378SN/A
1401706SN/Atemplate<> SparcFaultBase::FaultVals
14111851Sbrandon.potter@amd.com    SparcFault<DataInvalidTSBEntry>::vals =
142360SN/A    {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}};
14311760Sbrandon.potter@amd.com
14411760Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
14511851Sbrandon.potter@amd.com    SparcFault<DataAccessException>::vals =
14611760Sbrandon.potter@amd.com    {"data_access_exception", 0x030, 1201, {H, H, H}};
1476109Ssanchezd@stanford.edu
1481706SN/A//XXX This trap is apparently dropped from ua2005
14911851Sbrandon.potter@amd.com/*template<> SparcFaultBase::FaultVals
150378SN/A    SparcFault<DataAccessMMUMiss>::vals =
1516109Ssanchezd@stanford.edu    {"data_mmu", 0x031, 12, {H, H, H}};*/
1526109Ssanchezd@stanford.edu
15311851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
1546109Ssanchezd@stanford.edu    SparcFault<DataAccessError>::vals =
15511886Sbrandon.potter@amd.com    {"data_access_error", 0x032, 1210, {H, H, H}};
15611886Sbrandon.potter@amd.com
15711886Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
15811886Sbrandon.potter@amd.com    SparcFault<DataAccessProtection>::vals =
159378SN/A    {"data_access_protection", 0x033, 1207, {H, H, H}};
1601706SN/A
16111851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
162378SN/A    SparcFault<MemAddressNotAligned>::vals =
1635748SSteve.Reinhardt@amd.com    {"mem_address_not_aligned", 0x034, 1020, {H, H, H}};
1645748SSteve.Reinhardt@amd.com
16511851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
166378SN/A    SparcFault<LDDFMemAddressNotAligned>::vals =
167378SN/A    {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}};
1681706SN/A
16911851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
170378SN/A    SparcFault<STDFMemAddressNotAligned>::vals =
171378SN/A    {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}};
1721706SN/A
17311851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
174378SN/A    SparcFault<PrivilegedAction>::vals =
1754118Sgblack@eecs.umich.edu    {"privileged_action", 0x037, 1110, {H, H, SH}};
1764118Sgblack@eecs.umich.edu
17711851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
1784118Sgblack@eecs.umich.edu    SparcFault<LDQFMemAddressNotAligned>::vals =
179378SN/A    {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}};
1801706SN/A
18111851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
182378SN/A    SparcFault<STQFMemAddressNotAligned>::vals =
18313568Sbrandon.potter@amd.com    {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}};
18413568Sbrandon.potter@amd.com
18513568Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
18613568Sbrandon.potter@amd.com    SparcFault<InstructionRealTranslationMiss>::vals =
187378SN/A    {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}};
1881706SN/A
18911851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
190360SN/A    SparcFault<DataRealTranslationMiss>::vals =
1915513SMichael.Adler@intel.com    {"data_real_translation_miss", 0x03F, 1203, {H, H, H}};
1925513SMichael.Adler@intel.com
19311851Sbrandon.potter@amd.com//XXX This trap is apparently dropped from ua2005
1945513SMichael.Adler@intel.com/*template<> SparcFaultBase::FaultVals
19510203SAli.Saidi@ARM.com    SparcFault<AsyncDataError>::vals =
19610203SAli.Saidi@ARM.com    {"async_data", 0x040, 2, {H, H, H}};*/
19711851Sbrandon.potter@amd.com
19810203SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals
1995513SMichael.Adler@intel.com    SparcFault<InterruptLevelN>::vals =
20011851Sbrandon.potter@amd.com    {"interrupt_level_n", 0x041, 0, {P, P, SH}};
2015513SMichael.Adler@intel.com
202511SN/Atemplate<> SparcFaultBase::FaultVals
20310633Smichaelupton@gmail.com    SparcFault<HstickMatch>::vals =
20411851Sbrandon.potter@amd.com    {"hstick_match", 0x05E, 1601, {H, H, H}};
20510633Smichaelupton@gmail.com
2061706SN/Atemplate<> SparcFaultBase::FaultVals
20711851Sbrandon.potter@amd.com    SparcFault<TrapLevelZero>::vals =
208511SN/A    {"trap_level_zero", 0x05F, 202, {H, H, SH}};
20912795Smattdsinclair@gmail.com
21012795Smattdsinclair@gmail.comtemplate<> SparcFaultBase::FaultVals
21112795Smattdsinclair@gmail.com    SparcFault<PAWatchpoint>::vals =
21212795Smattdsinclair@gmail.com    {"PA_watchpoint", 0x061, 1209, {H, H, H}};
21312796Smattdsinclair@gmail.com
21412796Smattdsinclair@gmail.comtemplate<> SparcFaultBase::FaultVals
21512796Smattdsinclair@gmail.com    SparcFault<VAWatchpoint>::vals =
21612796Smattdsinclair@gmail.com    {"VA_watchpoint", 0x062, 1120, {P, P, SH}};
2175513SMichael.Adler@intel.com
2185513SMichael.Adler@intel.comtemplate<> SparcFaultBase::FaultVals
21911851Sbrandon.potter@amd.com    SparcFault<FastInstructionAccessMMUMiss>::vals =
2205513SMichael.Adler@intel.com    {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}};
22113031Sbrandon.potter@amd.com
22213031Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
22313031Sbrandon.potter@amd.com    SparcFault<FastDataAccessMMUMiss>::vals =
22413031Sbrandon.potter@amd.com    {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}};
22513031Sbrandon.potter@amd.com
22613031Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
22713031Sbrandon.potter@amd.com    SparcFault<FastDataAccessProtection>::vals =
22813031Sbrandon.potter@amd.com    {"fast_data_access_protection", 0x06C, 1207, {H, H, H}};
22913031Sbrandon.potter@amd.com
23013031Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
23113031Sbrandon.potter@amd.com    SparcFault<InstructionBreakpoint>::vals =
23213031Sbrandon.potter@amd.com    {"instruction_break", 0x076, 610, {H, H, H}};
233511SN/A
2341706SN/Atemplate<> SparcFaultBase::FaultVals
23511851Sbrandon.potter@amd.com    SparcFault<CpuMondo>::vals =
2361706SN/A    {"cpu_mondo", 0x07C, 1608, {P, P, SH}};
2371706SN/A
2381706SN/Atemplate<> SparcFaultBase::FaultVals
2391706SN/A    SparcFault<DevMondo>::vals =
24011851Sbrandon.potter@amd.com    {"dev_mondo", 0x07D, 1611, {P, P, SH}};
2411706SN/A
2421706SN/Atemplate<> SparcFaultBase::FaultVals
2431706SN/A    SparcFault<ResumeableError>::vals =
2441706SN/A    {"resume_error", 0x07E, 3330, {P, P, SH}};
24511851Sbrandon.potter@amd.com
2461706SN/Atemplate<> SparcFaultBase::FaultVals
247511SN/A    SparcFault<SpillNNormal>::vals =
2486703Svince@csl.cornell.edu    {"spill_n_normal", 0x080, 900, {P, P, H}};
2496703Svince@csl.cornell.edu
25011851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
2516703Svince@csl.cornell.edu    SparcFault<SpillNOther>::vals =
2526685Stjones1@inf.ed.ac.uk    {"spill_n_other", 0x0A0, 900, {P, P, H}};
2536685Stjones1@inf.ed.ac.uk
25411851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
2556685Stjones1@inf.ed.ac.uk    SparcFault<FillNNormal>::vals =
2566685Stjones1@inf.ed.ac.uk    {"fill_n_normal", 0x0C0, 900, {P, P, H}};
2575513SMichael.Adler@intel.com
2585513SMichael.Adler@intel.comtemplate<> SparcFaultBase::FaultVals
25911851Sbrandon.potter@amd.com    SparcFault<FillNOther>::vals =
2605513SMichael.Adler@intel.com    {"fill_n_other", 0x0E0, 900, {P, P, H}};
26111885Sbrandon.potter@amd.com
26211885Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
26311885Sbrandon.potter@amd.com    SparcFault<TrapInstruction>::vals =
2645513SMichael.Adler@intel.com    {"trap_instruction", 0x100, 1602, {P, P, H}};
2651999SN/A
2661999SN/A#if !FULL_SYSTEM
26711851Sbrandon.potter@amd.comtemplate<> SparcFaultBase::FaultVals
2681999SN/A    SparcFault<PageTableFault>::vals =
26911885Sbrandon.potter@amd.com    {"page_table_fault", 0x0000, 0, {SH, SH, SH}};
27011885Sbrandon.potter@amd.com#endif
27111885Sbrandon.potter@amd.com
2721999SN/A/**
2731999SN/A * This causes the thread context to enter RED state. This causes the side
2741999SN/A * effects which go with entering RED state because of a trap.
27511851Sbrandon.potter@amd.com */
2761999SN/A
2773079Sstever@eecs.umich.eduvoid enterREDState(ThreadContext *tc)
2783079Sstever@eecs.umich.edu{
27911851Sbrandon.potter@amd.com    //@todo Disable the mmu?
2803079Sstever@eecs.umich.edu    //@todo Disable watchpoints?
28111908SBrandon.Potter@amd.com    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
28211908SBrandon.Potter@amd.com    //HPSTATE.red = 1
28311908SBrandon.Potter@amd.com    HPSTATE |= (1 << 5);
28411908SBrandon.Potter@amd.com    //HPSTATE.hpriv = 1
28511875Sbrandon.potter@amd.com    HPSTATE |= (1 << 2);
2862093SN/A    tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE);
28711851Sbrandon.potter@amd.com    //PSTATE.priv is set to 1 here. The manual says it should be 0, but
2882093SN/A    //Legion sets it to 1.
2892687Sksewell@umich.edu    MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
2902687Sksewell@umich.edu    PSTATE |= (1 << 2);
29111851Sbrandon.potter@amd.com    tc->setMiscRegWithEffect(MISCREG_PSTATE, PSTATE);
2922687Sksewell@umich.edu}
2932238SN/A
2942238SN/A/**
29511851Sbrandon.potter@amd.com * This sets everything up for a RED state trap except for actually jumping to
2962238SN/A * the handler.
29711908SBrandon.Potter@amd.com */
29811908SBrandon.Potter@amd.com
29911908SBrandon.Potter@amd.comvoid doREDFault(ThreadContext *tc, TrapType tt)
30011908SBrandon.Potter@amd.com{
30111908SBrandon.Potter@amd.com    MiscReg TL = tc->readMiscReg(MISCREG_TL);
30211908SBrandon.Potter@amd.com    MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
30311908SBrandon.Potter@amd.com    MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
30411908SBrandon.Potter@amd.com    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
3052238SN/A    MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
3062238SN/A    MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
30711851Sbrandon.potter@amd.com    MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
3082238SN/A    MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
30913571Sbrandon.potter@amd.com    MiscReg GL = tc->readMiscReg(MISCREG_GL);
31013571Sbrandon.potter@amd.com    MiscReg PC = tc->readPC();
31113571Sbrandon.potter@amd.com    MiscReg NPC = tc->readNextPC();
31213571Sbrandon.potter@amd.com
31313568Sbrandon.potter@amd.com    TL++;
31413568Sbrandon.potter@amd.com
31513568Sbrandon.potter@amd.com    //set TSTATE.gl to gl
31613568Sbrandon.potter@amd.com    replaceBits(TSTATE, 42, 40, GL);
31713568Sbrandon.potter@amd.com    //set TSTATE.ccr to ccr
31813568Sbrandon.potter@amd.com    replaceBits(TSTATE, 39, 32, CCR);
31913568Sbrandon.potter@amd.com    //set TSTATE.asi to asi
32013568Sbrandon.potter@amd.com    replaceBits(TSTATE, 31, 24, ASI);
32113568Sbrandon.potter@amd.com    //set TSTATE.pstate to pstate
32213568Sbrandon.potter@amd.com    replaceBits(TSTATE, 20, 8, PSTATE);
32313568Sbrandon.potter@amd.com    //set TSTATE.cwp to cwp
32413568Sbrandon.potter@amd.com    replaceBits(TSTATE, 4, 0, CWP);
32513448Sciro.santilli@arm.com
32613031Sbrandon.potter@amd.com    //Write back TSTATE
32713031Sbrandon.potter@amd.com    tc->setMiscReg(MISCREG_TSTATE, TSTATE);
32813031Sbrandon.potter@amd.com
32913448Sciro.santilli@arm.com    //set TPC to PC
33013031Sbrandon.potter@amd.com    tc->setMiscReg(MISCREG_TPC, PC);
33113539Sjavier.setoain@arm.com    //set TNPC to NPC
33213539Sjavier.setoain@arm.com    tc->setMiscReg(MISCREG_TNPC, NPC);
33313539Sjavier.setoain@arm.com
33413539Sjavier.setoain@arm.com    //set HTSTATE.hpstate to hpstate
33513539Sjavier.setoain@arm.com    tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
33613539Sjavier.setoain@arm.com
33713569Sbrandon.potter@amd.com    //TT = trap type;
33813569Sbrandon.potter@amd.com    tc->setMiscReg(MISCREG_TT, tt);
33913569Sbrandon.potter@amd.com
34013569Sbrandon.potter@amd.com    //Update GL
34113569Sbrandon.potter@amd.com    tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
34213569Sbrandon.potter@amd.com
34313569Sbrandon.potter@amd.com    //set PSTATE.mm to 00
34413569Sbrandon.potter@amd.com    //set PSTATE.pef to 1
34513569Sbrandon.potter@amd.com    PSTATE |= (1 << 4);
34613569Sbrandon.potter@amd.com    //set PSTATE.am to 0
34713569Sbrandon.potter@amd.com    PSTATE &= ~(1 << 3);
34813569Sbrandon.potter@amd.com/*    //set PSTATE.priv to 0
34913569Sbrandon.potter@amd.com    PSTATE &= ~(1 << 2);*/
35013569Sbrandon.potter@amd.com    //set PSTATE.ie to 0
35113569Sbrandon.potter@amd.com    //PSTATE.priv is set to 1 here. The manual says it should be 0, but
35213569Sbrandon.potter@amd.com    //Legion sets it to 1.
35313031Sbrandon.potter@amd.com    PSTATE |= (1 << 2);
3542238SN/A    //set PSTATE.cle to 0
35511851Sbrandon.potter@amd.com    PSTATE &= ~(1 << 9);
3562238SN/A    //PSTATE.tle is unchanged
3572238SN/A    //XXX Where is the tct bit?
3582238SN/A    //set PSTATE.tct to 0
35911851Sbrandon.potter@amd.com    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
3602238SN/A
3612238SN/A    //set HPSTATE.red to 1
3622238SN/A    HPSTATE |= (1 << 5);
36311851Sbrandon.potter@amd.com    //set HPSTATE.hpriv to 1
3642238SN/A    HPSTATE |= (1 << 2);
3652238SN/A    //set HPSTATE.ibe to 0
3662238SN/A    HPSTATE &= ~(1 << 10);
36711851Sbrandon.potter@amd.com    //set HPSTATE.tlz to 0
3682238SN/A    HPSTATE &= ~(1 << 0);
3692238SN/A    tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
3702238SN/A
37111851Sbrandon.potter@amd.com    bool changedCWP = true;
3722238SN/A    if(tt == 0x24)
3739455Smitch.hayenga+gem5@gmail.com        CWP++;
3749455Smitch.hayenga+gem5@gmail.com    else if(0x80 <= tt && tt <= 0xbf)
37511851Sbrandon.potter@amd.com        CWP += (CANSAVE + 2);
37610203SAli.Saidi@ARM.com    else if(0xc0 <= tt && tt <= 0xff)
37711851Sbrandon.potter@amd.com        CWP--;
37811851Sbrandon.potter@amd.com    else
3799455Smitch.hayenga+gem5@gmail.com        changedCWP = false;
38013571Sbrandon.potter@amd.com
38113571Sbrandon.potter@amd.com    if(changedCWP)
38213571Sbrandon.potter@amd.com    {
38313571Sbrandon.potter@amd.com        CWP = (CWP + NWindows) % NWindows;
38413571Sbrandon.potter@amd.com        tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
38513571Sbrandon.potter@amd.com    }
38613571Sbrandon.potter@amd.com}
38713571Sbrandon.potter@amd.com
38813571Sbrandon.potter@amd.com/**
38913571Sbrandon.potter@amd.com * This sets everything up for a normal trap except for actually jumping to
39013571Sbrandon.potter@amd.com * the handler.
39113571Sbrandon.potter@amd.com */
3929112Smarc.orr@gmail.com
39311906SBrandon.Potter@amd.comvoid doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
39411906SBrandon.Potter@amd.com{
3959112Smarc.orr@gmail.com    MiscReg TL = tc->readMiscReg(MISCREG_TL);
3969112Smarc.orr@gmail.com    MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
39711851Sbrandon.potter@amd.com    MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
3989112Smarc.orr@gmail.com    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
3999112Smarc.orr@gmail.com    MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
40011911SBrandon.Potter@amd.com    MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
4019112Smarc.orr@gmail.com    MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
40211911SBrandon.Potter@amd.com    MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
40311911SBrandon.Potter@amd.com    MiscReg GL = tc->readMiscReg(MISCREG_GL);
40411911SBrandon.Potter@amd.com    MiscReg PC = tc->readPC();
40511911SBrandon.Potter@amd.com    MiscReg NPC = tc->readNextPC();
40613642Sqtt2@cornell.edu
40713642Sqtt2@cornell.edu    //Increment the trap level
40813642Sqtt2@cornell.edu    TL++;
4099112Smarc.orr@gmail.com    tc->setMiscReg(MISCREG_TL, TL);
41011911SBrandon.Potter@amd.com
41111911SBrandon.Potter@amd.com    //Save off state
41211911SBrandon.Potter@amd.com
41311911SBrandon.Potter@amd.com    //set TSTATE.gl to gl
4149238Slluc.alvarez@bsc.es    replaceBits(TSTATE, 42, 40, GL);
41513642Sqtt2@cornell.edu    //set TSTATE.ccr to ccr
4169112Smarc.orr@gmail.com    replaceBits(TSTATE, 39, 32, CCR);
41711911SBrandon.Potter@amd.com    //set TSTATE.asi to asi
4189112Smarc.orr@gmail.com    replaceBits(TSTATE, 31, 24, ASI);
41913642Sqtt2@cornell.edu    //set TSTATE.pstate to pstate
42011911SBrandon.Potter@amd.com    replaceBits(TSTATE, 20, 8, PSTATE);
42111911SBrandon.Potter@amd.com    //set TSTATE.cwp to cwp
42211911SBrandon.Potter@amd.com    replaceBits(TSTATE, 4, 0, CWP);
42311911SBrandon.Potter@amd.com
4249112Smarc.orr@gmail.com    //Write back TSTATE
42511911SBrandon.Potter@amd.com    tc->setMiscReg(MISCREG_TSTATE, TSTATE);
42611911SBrandon.Potter@amd.com
42711911SBrandon.Potter@amd.com    //set TPC to PC
42811911SBrandon.Potter@amd.com    tc->setMiscReg(MISCREG_TPC, PC);
42911911SBrandon.Potter@amd.com    //set TNPC to NPC
43011911SBrandon.Potter@amd.com    tc->setMiscReg(MISCREG_TNPC, NPC);
4319112Smarc.orr@gmail.com
4329112Smarc.orr@gmail.com    //set HTSTATE.hpstate to hpstate
43313642Sqtt2@cornell.edu    tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
43413642Sqtt2@cornell.edu
43513642Sqtt2@cornell.edu    //TT = trap type;
43613642Sqtt2@cornell.edu    tc->setMiscReg(MISCREG_TT, tt);
43713642Sqtt2@cornell.edu
43811911SBrandon.Potter@amd.com    //Update the global register level
4399112Smarc.orr@gmail.com    if(!gotoHpriv)
44011911SBrandon.Potter@amd.com        tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
44111911SBrandon.Potter@amd.com    else
44213642Sqtt2@cornell.edu        tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
44313642Sqtt2@cornell.edu
44413650Smw828@cornell.edu    //PSTATE.mm is unchanged
44513650Smw828@cornell.edu    //PSTATE.pef = whether or not an fpu is present
44613650Smw828@cornell.edu    //XXX We'll say there's one present, even though there aren't
44713650Smw828@cornell.edu    //implementations for a decent number of the instructions
44813650Smw828@cornell.edu    PSTATE |= (1 << 4);
44913650Smw828@cornell.edu    //PSTATE.am = 0
45013650Smw828@cornell.edu    PSTATE &= ~(1 << 3);
45113650Smw828@cornell.edu    if(!gotoHpriv)
45213650Smw828@cornell.edu    {
45313650Smw828@cornell.edu        //PSTATE.priv = 1
45413650Smw828@cornell.edu        PSTATE |= (1 << 2);
45513650Smw828@cornell.edu        //PSTATE.cle = PSTATE.tle
45613650Smw828@cornell.edu        replaceBits(PSTATE, 9, 9, PSTATE >> 8);
45713650Smw828@cornell.edu    }
45813651Smw828@cornell.edu    else
45913651Smw828@cornell.edu    {
46013651Smw828@cornell.edu        //PSTATE.priv = 0
46113651Smw828@cornell.edu        //PSTATE.priv is set to 1 here. The manual says it should be 0, but
46213651Smw828@cornell.edu        //Legion sets it to 1.
46313651Smw828@cornell.edu        PSTATE |= (1 << 2);
46413651Smw828@cornell.edu        //PSTATE.cle = 0
46513651Smw828@cornell.edu        PSTATE &= ~(1 << 9);
46613651Smw828@cornell.edu    }
46713651Smw828@cornell.edu    //PSTATE.ie = 0
46813651Smw828@cornell.edu    PSTATE &= ~(1 << 1);
46913651Smw828@cornell.edu    //PSTATE.tle is unchanged
47013651Smw828@cornell.edu    //PSTATE.tct = 0
47113651Smw828@cornell.edu    //XXX Where exactly is this field?
47213651Smw828@cornell.edu    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
47313651Smw828@cornell.edu
47413651Smw828@cornell.edu    if(gotoHpriv)
47513651Smw828@cornell.edu    {
47613651Smw828@cornell.edu        //HPSTATE.red = 0
47713651Smw828@cornell.edu        HPSTATE &= ~(1 << 5);
47813651Smw828@cornell.edu        //HPSTATE.hpriv = 1
47913651Smw828@cornell.edu        HPSTATE |= (1 << 2);
48013651Smw828@cornell.edu        //HPSTATE.ibe = 0
48113651Smw828@cornell.edu        HPSTATE &= ~(1 << 10);
48213651Smw828@cornell.edu        //HPSTATE.tlz is unchanged
48313651Smw828@cornell.edu        tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
48413651Smw828@cornell.edu    }
48513651Smw828@cornell.edu
48613651Smw828@cornell.edu    bool changedCWP = true;
48713651Smw828@cornell.edu    if(tt == 0x24)
48813651Smw828@cornell.edu        CWP++;
48913651Smw828@cornell.edu    else if(0x80 <= tt && tt <= 0xbf)
49013651Smw828@cornell.edu        CWP += (CANSAVE + 2);
49113651Smw828@cornell.edu    else if(0xc0 <= tt && tt <= 0xff)
49213651Smw828@cornell.edu        CWP--;
49313651Smw828@cornell.edu    else
49413651Smw828@cornell.edu        changedCWP = false;
49513651Smw828@cornell.edu
49613651Smw828@cornell.edu    if(changedCWP)
49713651Smw828@cornell.edu    {
49813651Smw828@cornell.edu        CWP = (CWP + NWindows) % NWindows;
49913651Smw828@cornell.edu        tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
50013651Smw828@cornell.edu    }
50113651Smw828@cornell.edu}
50213651Smw828@cornell.edu
50313651Smw828@cornell.eduvoid getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
50413651Smw828@cornell.edu{
50513651Smw828@cornell.edu    //XXX The following constant might belong in a header file.
50613651Smw828@cornell.edu    const Addr RSTVAddr = 0xFFF0000000ULL;
50713651Smw828@cornell.edu    PC = RSTVAddr | ((TT << 5) & 0xFF);
50813651Smw828@cornell.edu    NPC = PC + sizeof(MachInst);
50913651Smw828@cornell.edu}
51013651Smw828@cornell.edu
51113651Smw828@cornell.eduvoid getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT)
51213651Smw828@cornell.edu{
51313651Smw828@cornell.edu    Addr HTBA = tc->readMiscReg(MISCREG_HTBA);
51413651Smw828@cornell.edu    PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
51513651Smw828@cornell.edu    NPC = PC + sizeof(MachInst);
51613651Smw828@cornell.edu}
51713651Smw828@cornell.edu
51813651Smw828@cornell.eduvoid getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL)
51913651Smw828@cornell.edu{
52013651Smw828@cornell.edu    Addr TBA = tc->readMiscReg(MISCREG_TBA);
52113651Smw828@cornell.edu    PC = (TBA & ~mask(15)) |
52213651Smw828@cornell.edu        (TL > 1 ? (1 << 14) : 0) |
52313651Smw828@cornell.edu        ((TT << 5) & mask(14));
52413651Smw828@cornell.edu    NPC = PC + sizeof(MachInst);
52513651Smw828@cornell.edu}
52613651Smw828@cornell.edu
52713651Smw828@cornell.edu#if FULL_SYSTEM
52813651Smw828@cornell.edu
5299112Smarc.orr@gmail.comvoid SparcFaultBase::invoke(ThreadContext * tc)
53011911SBrandon.Potter@amd.com{
53111911SBrandon.Potter@amd.com    //panic("Invoking a second fault!\n");
5329112Smarc.orr@gmail.com    FaultBase::invoke(tc);
5339112Smarc.orr@gmail.com    countStat()++;
5342238SN/A
5352238SN/A    //We can refer to this to see what the trap level -was-, but something
5362238SN/A    //in the middle could change it in the regfile out from under us.
5372238SN/A    MiscReg TL = tc->readMiscReg(MISCREG_TL);
53811851Sbrandon.potter@amd.com    MiscReg TT = tc->readMiscReg(MISCREG_TT);
5392238SN/A    MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
5402238SN/A    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
5412238SN/A
54211851Sbrandon.potter@amd.com    Addr PC, NPC;
5432238SN/A
5442238SN/A    PrivilegeLevel current;
5452238SN/A    if(HPSTATE & (1 << 2))
54611851Sbrandon.potter@amd.com        current = Hyperprivileged;
5472238SN/A    else if(PSTATE & (1 << 2))
5482238SN/A        current = Privileged;
5492238SN/A    else
55011851Sbrandon.potter@amd.com        current = User;
5512238SN/A
5522238SN/A    PrivilegeLevel level = getNextLevel(current);
5531354SN/A
5541354SN/A    if(HPSTATE & (1 << 5) || TL == MaxTL - 1)
55510796Sbrandon.potter@amd.com    {
55610796Sbrandon.potter@amd.com        getREDVector(5, PC, NPC);
5571354SN/A        doREDFault(tc, TT);
5581354SN/A        //This changes the hpstate and pstate, so we need to make sure we
5591354SN/A        //save the old version on the trap stack in doREDFault.
5601354SN/A        enterREDState(tc);
5611354SN/A    }
5621354SN/A    else if(TL == MaxTL)
5631354SN/A    {
5641354SN/A        panic("Should go to error state here.. crap\n");
5651354SN/A        //Do error_state somehow?
5661354SN/A        //Probably inject a WDR fault using the interrupt mechanism.
56710796Sbrandon.potter@amd.com        //What should the PC and NPC be set to?
5681354SN/A    }
56910796Sbrandon.potter@amd.com    else if(TL > MaxPTL && level == Privileged)
5701354SN/A    {
5711354SN/A        //guest_watchdog fault
5721354SN/A        doNormalFault(tc, trapType(), true);
5731354SN/A        getHyperVector(tc, PC, NPC, 2);
57410796Sbrandon.potter@amd.com    }
57510796Sbrandon.potter@amd.com    else if(level == Hyperprivileged)
57610796Sbrandon.potter@amd.com    {
57710796Sbrandon.potter@amd.com        doNormalFault(tc, trapType(), true);
57810796Sbrandon.potter@amd.com        getHyperVector(tc, PC, NPC, trapType());
57910796Sbrandon.potter@amd.com    }
58010796Sbrandon.potter@amd.com    else
58110796Sbrandon.potter@amd.com    {
58210796Sbrandon.potter@amd.com        doNormalFault(tc, trapType(), false);
58310796Sbrandon.potter@amd.com        getPrivVector(tc, PC, NPC, trapType(), TL+1);
58410796Sbrandon.potter@amd.com    }
585360SN/A
586360SN/A    tc->setPC(PC);
587360SN/A    tc->setNextPC(NPC);
588360SN/A    tc->setNextNPC(NPC + sizeof(MachInst));
589360SN/A}
590360SN/A
591360SN/Avoid PowerOnReset::invoke(ThreadContext * tc)
59211759Sbrandon.potter@amd.com{
5933113Sgblack@eecs.umich.edu    //For SPARC, when a system is first started, there is a power
5943113Sgblack@eecs.umich.edu    //on reset Trap which sets the processor into the following state.
5953113Sgblack@eecs.umich.edu    //Bits that aren't set aren't defined on startup.
5963113Sgblack@eecs.umich.edu
5973113Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TL, MaxTL);
5983113Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TT, trapType());
5993113Sgblack@eecs.umich.edu    tc->setMiscRegWithEffect(MISCREG_GL, MaxGL);
6003113Sgblack@eecs.umich.edu
6013113Sgblack@eecs.umich.edu    //Turn on pef and priv, set everything else to 0
6023113Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_PSTATE, (1 << 4) | (1 << 2));
6033113Sgblack@eecs.umich.edu
6043113Sgblack@eecs.umich.edu    //Turn on red and hpriv, set everything else to 0
6053113Sgblack@eecs.umich.edu    MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
60612032Sandreas.sandberg@arm.com    //HPSTATE.red = 1
6073113Sgblack@eecs.umich.edu    HPSTATE |= (1 << 5);
6083113Sgblack@eecs.umich.edu    //HPSTATE.hpriv = 1
6094189Sgblack@eecs.umich.edu    HPSTATE |= (1 << 2);
6104189Sgblack@eecs.umich.edu    //HPSTATE.ibe = 0
6113113Sgblack@eecs.umich.edu    HPSTATE &= ~(1 << 10);
6123113Sgblack@eecs.umich.edu    //HPSTATE.tlz = 0
6133113Sgblack@eecs.umich.edu    HPSTATE &= ~(1 << 0);
6143113Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
6158737Skoansin.tan@gmail.com
6163113Sgblack@eecs.umich.edu    //The tick register is unreadable by nonprivileged software
6178737Skoansin.tan@gmail.com    tc->setMiscReg(MISCREG_TICK, 1ULL << 63);
6183277Sgblack@eecs.umich.edu
6195515SMichael.Adler@intel.com    //Enter RED state. We do this last so that the actual state preserved in
6205515SMichael.Adler@intel.com    //the trap stack is the state from before this fault.
6215515SMichael.Adler@intel.com    enterREDState(tc);
6225515SMichael.Adler@intel.com
6235515SMichael.Adler@intel.com    Addr PC, NPC;
6248737Skoansin.tan@gmail.com    getREDVector(trapType(), PC, NPC);
6253277Sgblack@eecs.umich.edu    tc->setPC(PC);
6268737Skoansin.tan@gmail.com    tc->setNextPC(NPC);
6273277Sgblack@eecs.umich.edu    tc->setNextNPC(NPC + sizeof(MachInst));
6288737Skoansin.tan@gmail.com
6293277Sgblack@eecs.umich.edu    //These registers are specified as "undefined" after a POR, and they
6308737Skoansin.tan@gmail.com    //should have reasonable values after the miscregfile is reset
6313113Sgblack@eecs.umich.edu    /*
6323113Sgblack@eecs.umich.edu    // Clear all the soft interrupt bits
6333113Sgblack@eecs.umich.edu    softint = 0;
6343113Sgblack@eecs.umich.edu    // disable timer compare interrupts, reset tick_cmpr
6358737Skoansin.tan@gmail.com    tc->setMiscReg(MISCREG_
6363113Sgblack@eecs.umich.edu    tick_cmprFields.int_dis = 1;
6378737Skoansin.tan@gmail.com    tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6383114Sgblack@eecs.umich.edu    stickFields.npt = 1; //The TICK register is unreadable by by !priv
6398737Skoansin.tan@gmail.com    stick_cmprFields.int_dis = 1; // disable timer compare interrupts
6403114Sgblack@eecs.umich.edu    stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6418737Skoansin.tan@gmail.com
6423114Sgblack@eecs.umich.edu    tt[tl] = _trapType;
6438737Skoansin.tan@gmail.com
64411906SBrandon.Potter@amd.com    hintp = 0; // no interrupts pending
6454061Sgblack@eecs.umich.edu    hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
6464061Sgblack@eecs.umich.edu    hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
6478737Skoansin.tan@gmail.com    */
6483113Sgblack@eecs.umich.edu}
6498737Skoansin.tan@gmail.com
6503113Sgblack@eecs.umich.edu#else // !FULL_SYSTEM
6513113Sgblack@eecs.umich.edu
6523113Sgblack@eecs.umich.eduvoid SpillNNormal::invoke(ThreadContext *tc)
6533113Sgblack@eecs.umich.edu{
6543113Sgblack@eecs.umich.edu    doNormalFault(tc, trapType(), false);
65512032Sandreas.sandberg@arm.com
6563113Sgblack@eecs.umich.edu    Process *p = tc->getProcessPtr();
6573113Sgblack@eecs.umich.edu
6584189Sgblack@eecs.umich.edu    //XXX This will only work in faults from a SparcLiveProcess
6594189Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
6603113Sgblack@eecs.umich.edu    assert(lp);
6613113Sgblack@eecs.umich.edu
6623113Sgblack@eecs.umich.edu    //Then adjust the PC and NPC
6638737Skoansin.tan@gmail.com    Addr spillStart = lp->readSpillStart();
6643113Sgblack@eecs.umich.edu    tc->setPC(spillStart);
6658737Skoansin.tan@gmail.com    tc->setNextPC(spillStart + sizeof(MachInst));
6663113Sgblack@eecs.umich.edu    tc->setNextNPC(spillStart + 2*sizeof(MachInst));
6678737Skoansin.tan@gmail.com}
6683113Sgblack@eecs.umich.edu
6693113Sgblack@eecs.umich.eduvoid FillNNormal::invoke(ThreadContext *tc)
6703113Sgblack@eecs.umich.edu{
6713113Sgblack@eecs.umich.edu    doNormalFault(tc, trapType(), false);
6723113Sgblack@eecs.umich.edu
6733113Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
6743113Sgblack@eecs.umich.edu
67511906SBrandon.Potter@amd.com    //XXX This will only work in faults from a SparcLiveProcess
6763113Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
67712032Sandreas.sandberg@arm.com    assert(lp);
6788852Sandreas.hansson@arm.com
67911906SBrandon.Potter@amd.com    //Then adjust the PC and NPC
6803113Sgblack@eecs.umich.edu    Addr fillStart = lp->readFillStart();
6813113Sgblack@eecs.umich.edu    tc->setPC(fillStart);
6823113Sgblack@eecs.umich.edu    tc->setNextPC(fillStart + sizeof(MachInst));
6833113Sgblack@eecs.umich.edu    tc->setNextNPC(fillStart + 2*sizeof(MachInst));
6843113Sgblack@eecs.umich.edu}
6853113Sgblack@eecs.umich.edu
6863113Sgblack@eecs.umich.eduvoid PageTableFault::invoke(ThreadContext *tc)
6873113Sgblack@eecs.umich.edu{
68812032Sandreas.sandberg@arm.com    Process *p = tc->getProcessPtr();
6898852Sandreas.hansson@arm.com
69011906SBrandon.Potter@amd.com    // address is higher than the stack region or in the current stack region
6913113Sgblack@eecs.umich.edu    if (vaddr > p->stack_base || vaddr > p->stack_min)
6923113Sgblack@eecs.umich.edu        FaultBase::invoke(tc);
6933113Sgblack@eecs.umich.edu
6946686Stjones1@inf.ed.ac.uk    // We've accessed the next page
6953113Sgblack@eecs.umich.edu    if (vaddr > p->stack_min - PageBytes) {
6963113Sgblack@eecs.umich.edu        p->stack_min -= PageBytes;
6973113Sgblack@eecs.umich.edu        if (p->stack_base - p->stack_min > 8*1024*1024)
69811759Sbrandon.potter@amd.com            fatal("Over max stack size for one thread\n");
69912032Sandreas.sandberg@arm.com        p->pTable->allocate(p->stack_min, PageBytes);
70011759Sbrandon.potter@amd.com        warn("Increasing stack size by one page.");
70111759Sbrandon.potter@amd.com    } else {
70211759Sbrandon.potter@amd.com        FaultBase::invoke(tc);
70311759Sbrandon.potter@amd.com    }
70411759Sbrandon.potter@amd.com}
70511812Sbaz21@cam.ac.uk
70611812Sbaz21@cam.ac.uk#endif
70711812Sbaz21@cam.ac.uk
70811759Sbrandon.potter@amd.com} // namespace SparcISA
70911812Sbaz21@cam.ac.uk
71011759Sbrandon.potter@amd.com