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