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