faults.cc revision 7400
12381SN/A/* 28853Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 38711Sandreas.hansson@arm.com * All rights reserved. 48711Sandreas.hansson@arm.com * 58711Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68711Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78711Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88711Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98711Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108711Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118711Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128711Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138711Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 142381SN/A * this software without specific prior written permission. 152381SN/A * 162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272381SN/A * 282381SN/A * Authors: Gabe Black 292381SN/A * Kevin Lim 302381SN/A */ 312381SN/A 322381SN/A#include <algorithm> 332381SN/A 342381SN/A#include "arch/sparc/faults.hh" 352381SN/A#include "arch/sparc/isa_traits.hh" 362381SN/A#include "arch/sparc/types.hh" 372381SN/A#include "base/bitfield.hh" 382381SN/A#include "base/trace.hh" 392665Ssaidi@eecs.umich.edu#include "config/full_system.hh" 402665Ssaidi@eecs.umich.edu#include "cpu/base.hh" 418853Sandreas.hansson@arm.com#include "cpu/thread_context.hh" 428922Swilliam.wang@arm.com#if !FULL_SYSTEM 432381SN/A#include "arch/sparc/process.hh" 442381SN/A#include "mem/page_table.hh" 452381SN/A#include "sim/process.hh" 462381SN/A#endif 478922Swilliam.wang@arm.com 482381SN/Ausing namespace std; 492381SN/A 502381SN/Anamespace SparcISA 512381SN/A{ 522381SN/A 532381SN/Atemplate<> SparcFaultBase::FaultVals 542381SN/A SparcFault<PowerOnReset>::vals = 559235Sandreas.hansson@arm.com {"power_on_reset", 0x001, 0, {H, H, H}}; 562381SN/A 572381SN/Atemplate<> SparcFaultBase::FaultVals 588922Swilliam.wang@arm.com SparcFault<WatchDogReset>::vals = 598922Swilliam.wang@arm.com {"watch_dog_reset", 0x002, 120, {H, H, H}}; 602407SN/A 612407SN/Atemplate<> SparcFaultBase::FaultVals 622407SN/A SparcFault<ExternallyInitiatedReset>::vals = 632407SN/A {"externally_initiated_reset", 0x003, 110, {H, H, H}}; 642407SN/A 659235Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 669235Sandreas.hansson@arm.com SparcFault<SoftwareInitiatedReset>::vals = 679235Sandreas.hansson@arm.com {"software_initiated_reset", 0x004, 130, {SH, SH, H}}; 682407SN/A 693401Sktlim@umich.edutemplate<> SparcFaultBase::FaultVals 703401Sktlim@umich.edu SparcFault<REDStateException>::vals = 712381SN/A {"RED_state_exception", 0x005, 1, {H, H, H}}; 728922Swilliam.wang@arm.com 738922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 749087Sandreas.hansson@arm.com SparcFault<StoreError>::vals = 752381SN/A {"store_error", 0x007, 201, {H, H, H}}; 768708Sandreas.hansson@arm.com 772381SN/Atemplate<> SparcFaultBase::FaultVals 788922Swilliam.wang@arm.com SparcFault<InstructionAccessException>::vals = 798922Swilliam.wang@arm.com {"instruction_access_exception", 0x008, 300, {H, H, H}}; 808922Swilliam.wang@arm.com 818922Swilliam.wang@arm.com//XXX This trap is apparently dropped from ua2005 828922Swilliam.wang@arm.com/*template<> SparcFaultBase::FaultVals 838922Swilliam.wang@arm.com SparcFault<InstructionAccessMMUMiss>::vals = 845476Snate@binkert.org {"inst_mmu", 0x009, 2, {H, H, H}};*/ 852640Sstever@eecs.umich.edu 868965Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 878965Sandreas.hansson@arm.com SparcFault<InstructionAccessError>::vals = 889031Sandreas.hansson@arm.com {"instruction_access_error", 0x00A, 400, {H, H, H}}; 898965Sandreas.hansson@arm.com 909031Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 918965Sandreas.hansson@arm.com SparcFault<IllegalInstruction>::vals = 928922Swilliam.wang@arm.com {"illegal_instruction", 0x010, 620, {H, H, H}}; 938922Swilliam.wang@arm.com 948922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 958922Swilliam.wang@arm.com SparcFault<PrivilegedOpcode>::vals = 968922Swilliam.wang@arm.com {"privileged_opcode", 0x011, 700, {P, SH, SH}}; 978922Swilliam.wang@arm.com 988922Swilliam.wang@arm.com//XXX This trap is apparently dropped from ua2005 998922Swilliam.wang@arm.com/*template<> SparcFaultBase::FaultVals 1008965Sandreas.hansson@arm.com SparcFault<UnimplementedLDD>::vals = 1018922Swilliam.wang@arm.com {"unimp_ldd", 0x012, 6, {H, H, H}};*/ 1029031Sandreas.hansson@arm.com 1038922Swilliam.wang@arm.com//XXX This trap is apparently dropped from ua2005 1048922Swilliam.wang@arm.com/*template<> SparcFaultBase::FaultVals 1058922Swilliam.wang@arm.com SparcFault<UnimplementedSTD>::vals = 1068922Swilliam.wang@arm.com {"unimp_std", 0x013, 6, {H, H, H}};*/ 1078922Swilliam.wang@arm.com 1083401Sktlim@umich.edutemplate<> SparcFaultBase::FaultVals 1092381SN/A SparcFault<FpDisabled>::vals = 1102640Sstever@eecs.umich.edu {"fp_disabled", 0x020, 800, {P, P, H}}; 1112640Sstever@eecs.umich.edu 1128922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 1134190Ssaidi@eecs.umich.edu SparcFault<FpExceptionIEEE754>::vals = 1148965Sandreas.hansson@arm.com {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}}; 1159031Sandreas.hansson@arm.com 1168965Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1178922Swilliam.wang@arm.com SparcFault<FpExceptionOther>::vals = 1188922Swilliam.wang@arm.com {"fp_exception_other", 0x022, 1110, {P, P, H}}; 1198922Swilliam.wang@arm.com 1209294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1219294Sandreas.hansson@arm.com SparcFault<TagOverflow>::vals = 1229294Sandreas.hansson@arm.com {"tag_overflow", 0x023, 1400, {P, P, H}}; 1239294Sandreas.hansson@arm.com 1249294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1259294Sandreas.hansson@arm.com SparcFault<CleanWindow>::vals = 1269294Sandreas.hansson@arm.com {"clean_window", 0x024, 1010, {P, P, H}}; 1279294Sandreas.hansson@arm.com 1289294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1299294Sandreas.hansson@arm.com SparcFault<DivisionByZero>::vals = 1309294Sandreas.hansson@arm.com {"division_by_zero", 0x028, 1500, {P, P, H}}; 1319294Sandreas.hansson@arm.com 1329294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1339294Sandreas.hansson@arm.com SparcFault<InternalProcessorError>::vals = 1349294Sandreas.hansson@arm.com {"internal_processor_error", 0x029, 4, {H, H, H}}; 1359294Sandreas.hansson@arm.com 1369294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1379294Sandreas.hansson@arm.com SparcFault<InstructionInvalidTSBEntry>::vals = 1389294Sandreas.hansson@arm.com {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}}; 1399294Sandreas.hansson@arm.com 1409294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1419294Sandreas.hansson@arm.com SparcFault<DataInvalidTSBEntry>::vals = 1429294Sandreas.hansson@arm.com {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}}; 1439294Sandreas.hansson@arm.com 1449294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1459294Sandreas.hansson@arm.com SparcFault<DataAccessException>::vals = 1469294Sandreas.hansson@arm.com {"data_access_exception", 0x030, 1201, {H, H, H}}; 1479294Sandreas.hansson@arm.com 1489294Sandreas.hansson@arm.com//XXX This trap is apparently dropped from ua2005 1499294Sandreas.hansson@arm.com/*template<> SparcFaultBase::FaultVals 1509294Sandreas.hansson@arm.com SparcFault<DataAccessMMUMiss>::vals = 1519294Sandreas.hansson@arm.com {"data_mmu", 0x031, 12, {H, H, H}};*/ 1529294Sandreas.hansson@arm.com 1539294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1549294Sandreas.hansson@arm.com SparcFault<DataAccessError>::vals = 1559294Sandreas.hansson@arm.com {"data_access_error", 0x032, 1210, {H, H, H}}; 1569294Sandreas.hansson@arm.com 1579294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1589294Sandreas.hansson@arm.com SparcFault<DataAccessProtection>::vals = 1599294Sandreas.hansson@arm.com {"data_access_protection", 0x033, 1207, {H, H, H}}; 1609294Sandreas.hansson@arm.com 1619294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1629294Sandreas.hansson@arm.com SparcFault<MemAddressNotAligned>::vals = 1639294Sandreas.hansson@arm.com {"mem_address_not_aligned", 0x034, 1020, {H, H, H}}; 1649294Sandreas.hansson@arm.com 1659294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1669294Sandreas.hansson@arm.com SparcFault<LDDFMemAddressNotAligned>::vals = 1679294Sandreas.hansson@arm.com {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}}; 1689294Sandreas.hansson@arm.com 1699294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1709294Sandreas.hansson@arm.com SparcFault<STDFMemAddressNotAligned>::vals = 1718922Swilliam.wang@arm.com {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}}; 1728922Swilliam.wang@arm.com 1738922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 1749294Sandreas.hansson@arm.com SparcFault<PrivilegedAction>::vals = 1759294Sandreas.hansson@arm.com {"privileged_action", 0x037, 1110, {H, H, SH}}; 1769294Sandreas.hansson@arm.com 1779294Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1789294Sandreas.hansson@arm.com SparcFault<LDQFMemAddressNotAligned>::vals = 1798922Swilliam.wang@arm.com {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}}; 1809294Sandreas.hansson@arm.com 1818922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 1828922Swilliam.wang@arm.com SparcFault<STQFMemAddressNotAligned>::vals = 1838975Sandreas.hansson@arm.com {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}}; 1848975Sandreas.hansson@arm.com 1858922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 1868922Swilliam.wang@arm.com SparcFault<InstructionRealTranslationMiss>::vals = 1878922Swilliam.wang@arm.com {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}}; 1888922Swilliam.wang@arm.com 1898922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 1908922Swilliam.wang@arm.com SparcFault<DataRealTranslationMiss>::vals = 1918965Sandreas.hansson@arm.com {"data_real_translation_miss", 0x03F, 1203, {H, H, H}}; 1929031Sandreas.hansson@arm.com 1938922Swilliam.wang@arm.com//XXX This trap is apparently dropped from ua2005 1948922Swilliam.wang@arm.com/*template<> SparcFaultBase::FaultVals 1959178Sandreas.hansson@arm.com SparcFault<AsyncDataError>::vals = 1969178Sandreas.hansson@arm.com {"async_data", 0x040, 2, {H, H, H}};*/ 1979178Sandreas.hansson@arm.com 1989178Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 1999294Sandreas.hansson@arm.com SparcFault<InterruptLevelN>::vals = 2009178Sandreas.hansson@arm.com {"interrupt_level_n", 0x040, 0, {P, P, SH}}; 2019178Sandreas.hansson@arm.com 2029178Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2039178Sandreas.hansson@arm.com SparcFault<HstickMatch>::vals = 2049178Sandreas.hansson@arm.com {"hstick_match", 0x05E, 1601, {H, H, H}}; 2059178Sandreas.hansson@arm.com 2068922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 2078948Sandreas.hansson@arm.com SparcFault<TrapLevelZero>::vals = 2088948Sandreas.hansson@arm.com {"trap_level_zero", 0x05F, 202, {H, H, SH}}; 2098948Sandreas.hansson@arm.com 2108948Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2118948Sandreas.hansson@arm.com SparcFault<InterruptVector>::vals = 2128948Sandreas.hansson@arm.com {"interrupt_vector", 0x060, 2630, {H, H, H}}; 2138948Sandreas.hansson@arm.com 2148948Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2158948Sandreas.hansson@arm.com SparcFault<PAWatchpoint>::vals = 2168948Sandreas.hansson@arm.com {"PA_watchpoint", 0x061, 1209, {H, H, H}}; 2178948Sandreas.hansson@arm.com 2188948Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2198948Sandreas.hansson@arm.com SparcFault<VAWatchpoint>::vals = 2208948Sandreas.hansson@arm.com {"VA_watchpoint", 0x062, 1120, {P, P, SH}}; 2218948Sandreas.hansson@arm.com 2228948Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2238948Sandreas.hansson@arm.com SparcFault<FastInstructionAccessMMUMiss>::vals = 2248948Sandreas.hansson@arm.com {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}}; 2258948Sandreas.hansson@arm.com 2268948Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2278975Sandreas.hansson@arm.com SparcFault<FastDataAccessMMUMiss>::vals = 2288975Sandreas.hansson@arm.com {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}}; 2298975Sandreas.hansson@arm.com 2308975Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2318975Sandreas.hansson@arm.com SparcFault<FastDataAccessProtection>::vals = 2328975Sandreas.hansson@arm.com {"fast_data_access_protection", 0x06C, 1207, {H, H, H}}; 2338975Sandreas.hansson@arm.com 2348975Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2358975Sandreas.hansson@arm.com SparcFault<InstructionBreakpoint>::vals = 2368975Sandreas.hansson@arm.com {"instruction_break", 0x076, 610, {H, H, H}}; 2378975Sandreas.hansson@arm.com 2388948Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2398948Sandreas.hansson@arm.com SparcFault<CpuMondo>::vals = 2408975Sandreas.hansson@arm.com {"cpu_mondo", 0x07C, 1608, {P, P, SH}}; 2418975Sandreas.hansson@arm.com 2428975Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2438975Sandreas.hansson@arm.com SparcFault<DevMondo>::vals = 2448975Sandreas.hansson@arm.com {"dev_mondo", 0x07D, 1611, {P, P, SH}}; 2458975Sandreas.hansson@arm.com 2468975Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2478948Sandreas.hansson@arm.com SparcFault<ResumableError>::vals = 2488975Sandreas.hansson@arm.com {"resume_error", 0x07E, 3330, {P, P, SH}}; 2498922Swilliam.wang@arm.com 2508922Swilliam.wang@arm.comtemplate<> SparcFaultBase::FaultVals 2519087Sandreas.hansson@arm.com SparcFault<SpillNNormal>::vals = 2529087Sandreas.hansson@arm.com {"spill_n_normal", 0x080, 900, {P, P, H}}; 2539087Sandreas.hansson@arm.com 2549716Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2559087Sandreas.hansson@arm.com SparcFault<SpillNOther>::vals = 2569087Sandreas.hansson@arm.com {"spill_n_other", 0x0A0, 900, {P, P, H}}; 2578922Swilliam.wang@arm.com 2588711Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2598922Swilliam.wang@arm.com SparcFault<FillNNormal>::vals = 2608922Swilliam.wang@arm.com {"fill_n_normal", 0x0C0, 900, {P, P, H}}; 2618922Swilliam.wang@arm.com 2628711Sandreas.hansson@arm.comtemplate<> SparcFaultBase::FaultVals 2638711Sandreas.hansson@arm.com SparcFault<FillNOther>::vals = 2648711Sandreas.hansson@arm.com {"fill_n_other", 0x0E0, 900, {P, P, H}}; 2658922Swilliam.wang@arm.com 2662381SN/Atemplate<> SparcFaultBase::FaultVals 2678711Sandreas.hansson@arm.com SparcFault<TrapInstruction>::vals = 2688922Swilliam.wang@arm.com {"trap_instruction", 0x100, 1602, {P, P, H}}; 2698922Swilliam.wang@arm.com 2708711Sandreas.hansson@arm.com/** 2718922Swilliam.wang@arm.com * This causes the thread context to enter RED state. This causes the side 2722381SN/A * effects which go with entering RED state because of a trap. 2732381SN/A */ 2742381SN/A 2752381SN/Avoid enterREDState(ThreadContext *tc) 2768922Swilliam.wang@arm.com{ 2772381SN/A //@todo Disable the mmu? 2789089Sandreas.hansson@arm.com //@todo Disable watchpoints? 2799089Sandreas.hansson@arm.com MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 2809089Sandreas.hansson@arm.com //HPSTATE.red = 1 2819089Sandreas.hansson@arm.com HPSTATE |= (1 << 5); 2829089Sandreas.hansson@arm.com //HPSTATE.hpriv = 1 2835314Sstever@gmail.com HPSTATE |= (1 << 2); 2845314Sstever@gmail.com tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); 2855314Sstever@gmail.com //PSTATE.priv is set to 1 here. The manual says it should be 0, but 2865314Sstever@gmail.com //Legion sets it to 1. 2878975Sandreas.hansson@arm.com MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 2888975Sandreas.hansson@arm.com PSTATE |= (1 << 2); 2898975Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_PSTATE, PSTATE); 2908975Sandreas.hansson@arm.com} 2918975Sandreas.hansson@arm.com 2928975Sandreas.hansson@arm.com/** 2938975Sandreas.hansson@arm.com * This sets everything up for a RED state trap except for actually jumping to 2948975Sandreas.hansson@arm.com * the handler. 2958975Sandreas.hansson@arm.com */ 2968975Sandreas.hansson@arm.com 2978975Sandreas.hansson@arm.comvoid doREDFault(ThreadContext *tc, TrapType tt) 2988975Sandreas.hansson@arm.com{ 2998975Sandreas.hansson@arm.com MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 3008975Sandreas.hansson@arm.com MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 3018975Sandreas.hansson@arm.com MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 3028975Sandreas.hansson@arm.com MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 3038975Sandreas.hansson@arm.com //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR); 3048975Sandreas.hansson@arm.com MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 3058975Sandreas.hansson@arm.com MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 3068975Sandreas.hansson@arm.com MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); 3078975Sandreas.hansson@arm.com //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE); 3088975Sandreas.hansson@arm.com MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3); 3098975Sandreas.hansson@arm.com MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 3108975Sandreas.hansson@arm.com MiscReg PC = tc->readPC(); 3118975Sandreas.hansson@arm.com MiscReg NPC = tc->readNextPC(); 3128975Sandreas.hansson@arm.com 3138975Sandreas.hansson@arm.com TL++; 3148975Sandreas.hansson@arm.com 3158975Sandreas.hansson@arm.com if (bits(PSTATE, 3,3)) { 3168975Sandreas.hansson@arm.com PC &= mask(32); 3178975Sandreas.hansson@arm.com NPC &= mask(32); 3188975Sandreas.hansson@arm.com } 3198975Sandreas.hansson@arm.com 3208975Sandreas.hansson@arm.com //set TSTATE.gl to gl 3219087Sandreas.hansson@arm.com replaceBits(TSTATE, 42, 40, GL); 3229087Sandreas.hansson@arm.com //set TSTATE.ccr to ccr 3239087Sandreas.hansson@arm.com replaceBits(TSTATE, 39, 32, CCR); 3249087Sandreas.hansson@arm.com //set TSTATE.asi to asi 3259087Sandreas.hansson@arm.com replaceBits(TSTATE, 31, 24, ASI); 3269087Sandreas.hansson@arm.com //set TSTATE.pstate to pstate 3279087Sandreas.hansson@arm.com replaceBits(TSTATE, 20, 8, PSTATE); 3289087Sandreas.hansson@arm.com //set TSTATE.cwp to cwp 3298975Sandreas.hansson@arm.com replaceBits(TSTATE, 4, 0, CWP); 3309325Sandreas.hansson@arm.com 3318975Sandreas.hansson@arm.com //Write back TSTATE 3329325Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 3338975Sandreas.hansson@arm.com 3348975Sandreas.hansson@arm.com //set TPC to PC 3358975Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_TPC, PC); 3362381SN/A //set TNPC to NPC 3372381SN/A tc->setMiscRegNoEffect(MISCREG_TNPC, NPC); 3388922Swilliam.wang@arm.com 3398922Swilliam.wang@arm.com //set HTSTATE.hpstate to hpstate 3408922Swilliam.wang@arm.com tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); 3418922Swilliam.wang@arm.com 3428922Swilliam.wang@arm.com //TT = trap type; 3438922Swilliam.wang@arm.com tc->setMiscRegNoEffect(MISCREG_TT, tt); 3449294Sandreas.hansson@arm.com 3458922Swilliam.wang@arm.com //Update GL 3468922Swilliam.wang@arm.com tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); 3478975Sandreas.hansson@arm.com 3488975Sandreas.hansson@arm.com PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit 3498922Swilliam.wang@arm.com PSTATE |= (1 << 4); //set PSTATE.pef to 1 3508922Swilliam.wang@arm.com tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); 3518922Swilliam.wang@arm.com 3528922Swilliam.wang@arm.com //set HPSTATE.red to 1 3538922Swilliam.wang@arm.com HPSTATE |= (1 << 5); 3548922Swilliam.wang@arm.com //set HPSTATE.hpriv to 1 3558965Sandreas.hansson@arm.com HPSTATE |= (1 << 2); 3569031Sandreas.hansson@arm.com //set HPSTATE.ibe to 0 3578922Swilliam.wang@arm.com HPSTATE &= ~(1 << 10); 3588922Swilliam.wang@arm.com //set HPSTATE.tlz to 0 3598922Swilliam.wang@arm.com HPSTATE &= ~(1 << 0); 3608948Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 3618948Sandreas.hansson@arm.com 3628948Sandreas.hansson@arm.com bool changedCWP = true; 3638948Sandreas.hansson@arm.com if(tt == 0x24) 3648948Sandreas.hansson@arm.com CWP++; 3658948Sandreas.hansson@arm.com else if(0x80 <= tt && tt <= 0xbf) 3668948Sandreas.hansson@arm.com CWP += (CANSAVE + 2); 3678948Sandreas.hansson@arm.com else if(0xc0 <= tt && tt <= 0xff) 3688948Sandreas.hansson@arm.com CWP--; 3698948Sandreas.hansson@arm.com else 3708948Sandreas.hansson@arm.com changedCWP = false; 3718948Sandreas.hansson@arm.com 3728948Sandreas.hansson@arm.com if(changedCWP) 3738948Sandreas.hansson@arm.com { 3748948Sandreas.hansson@arm.com CWP = (CWP + NWindows) % NWindows; 3758948Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CWP, CWP); 3768948Sandreas.hansson@arm.com } 3778948Sandreas.hansson@arm.com} 3788948Sandreas.hansson@arm.com 3798948Sandreas.hansson@arm.com/** 3808975Sandreas.hansson@arm.com * This sets everything up for a normal trap except for actually jumping to 3818975Sandreas.hansson@arm.com * the handler. 3828975Sandreas.hansson@arm.com */ 3838975Sandreas.hansson@arm.com 3848975Sandreas.hansson@arm.comvoid doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) 3858975Sandreas.hansson@arm.com{ 3868975Sandreas.hansson@arm.com MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 3878975Sandreas.hansson@arm.com MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 3888975Sandreas.hansson@arm.com MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 3898975Sandreas.hansson@arm.com MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 3908975Sandreas.hansson@arm.com //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR); 3918948Sandreas.hansson@arm.com MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 3928948Sandreas.hansson@arm.com MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 3938975Sandreas.hansson@arm.com MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); 3948975Sandreas.hansson@arm.com //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE); 3958975Sandreas.hansson@arm.com MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); 3968975Sandreas.hansson@arm.com MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 3978975Sandreas.hansson@arm.com MiscReg PC = tc->readPC(); 3988948Sandreas.hansson@arm.com MiscReg NPC = tc->readNextPC(); 3998975Sandreas.hansson@arm.com 4008948Sandreas.hansson@arm.com if (bits(PSTATE, 3,3)) { 4018948Sandreas.hansson@arm.com PC &= mask(32); 4029087Sandreas.hansson@arm.com NPC &= mask(32); 4039087Sandreas.hansson@arm.com } 4049087Sandreas.hansson@arm.com 4059087Sandreas.hansson@arm.com //Increment the trap level 4069087Sandreas.hansson@arm.com TL++; 4079087Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_TL, TL); 4089087Sandreas.hansson@arm.com 4098922Swilliam.wang@arm.com //Save off state 4108922Swilliam.wang@arm.com 4118922Swilliam.wang@arm.com //set TSTATE.gl to gl 4128922Swilliam.wang@arm.com replaceBits(TSTATE, 42, 40, GL); 4138922Swilliam.wang@arm.com //set TSTATE.ccr to ccr 4148922Swilliam.wang@arm.com replaceBits(TSTATE, 39, 32, CCR); 4158922Swilliam.wang@arm.com //set TSTATE.asi to asi 4168922Swilliam.wang@arm.com replaceBits(TSTATE, 31, 24, ASI); 4178922Swilliam.wang@arm.com //set TSTATE.pstate to pstate 4188922Swilliam.wang@arm.com replaceBits(TSTATE, 20, 8, PSTATE); 4198922Swilliam.wang@arm.com //set TSTATE.cwp to cwp 4209088Sandreas.hansson@arm.com replaceBits(TSTATE, 4, 0, CWP); 4219088Sandreas.hansson@arm.com 4229088Sandreas.hansson@arm.com //Write back TSTATE 4239088Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 4249088Sandreas.hansson@arm.com 4259088Sandreas.hansson@arm.com //set TPC to PC 4269088Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_TPC, PC); 4278922Swilliam.wang@arm.com //set TNPC to NPC 4288922Swilliam.wang@arm.com tc->setMiscRegNoEffect(MISCREG_TNPC, NPC); 4298922Swilliam.wang@arm.com 4308922Swilliam.wang@arm.com //set HTSTATE.hpstate to hpstate 4318922Swilliam.wang@arm.com tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); 4328922Swilliam.wang@arm.com 4338922Swilliam.wang@arm.com //TT = trap type; 4348922Swilliam.wang@arm.com tc->setMiscRegNoEffect(MISCREG_TT, tt); 4358922Swilliam.wang@arm.com 4368922Swilliam.wang@arm.com //Update the global register level 4378922Swilliam.wang@arm.com if (!gotoHpriv) 4389090Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxPGL)); 4398975Sandreas.hansson@arm.com else 4408975Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); 4418975Sandreas.hansson@arm.com 4428975Sandreas.hansson@arm.com //PSTATE.mm is unchanged 4439178Sandreas.hansson@arm.com PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present 4449178Sandreas.hansson@arm.com PSTATE &= ~(1 << 3); //PSTATE.am = 0 4459178Sandreas.hansson@arm.com PSTATE &= ~(1 << 1); //PSTATE.ie = 0 4469178Sandreas.hansson@arm.com //PSTATE.tle is unchanged 4479178Sandreas.hansson@arm.com //PSTATE.tct = 0 4489178Sandreas.hansson@arm.com 4499178Sandreas.hansson@arm.com if (gotoHpriv) 4509178Sandreas.hansson@arm.com { 4519178Sandreas.hansson@arm.com PSTATE &= ~(1 << 9); // PSTATE.cle = 0 4529178Sandreas.hansson@arm.com //The manual says PSTATE.priv should be 0, but Legion leaves it alone 4539178Sandreas.hansson@arm.com HPSTATE &= ~(1 << 5); //HPSTATE.red = 0 4549178Sandreas.hansson@arm.com HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1 4558975Sandreas.hansson@arm.com HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0 4568975Sandreas.hansson@arm.com //HPSTATE.tlz is unchanged 4578975Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 4588975Sandreas.hansson@arm.com } else { // we are going to priv 4598975Sandreas.hansson@arm.com PSTATE |= (1 << 2); //PSTATE.priv = 1 4608975Sandreas.hansson@arm.com replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle 4618975Sandreas.hansson@arm.com } 4628975Sandreas.hansson@arm.com tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); 4638975Sandreas.hansson@arm.com 4648975Sandreas.hansson@arm.com 4658975Sandreas.hansson@arm.com bool changedCWP = true; 4668975Sandreas.hansson@arm.com if (tt == 0x24) 4678975Sandreas.hansson@arm.com CWP++; 4688975Sandreas.hansson@arm.com else if (0x80 <= tt && tt <= 0xbf) 4698975Sandreas.hansson@arm.com CWP += (CANSAVE + 2); 4708975Sandreas.hansson@arm.com else if (0xc0 <= tt && tt <= 0xff) 4718975Sandreas.hansson@arm.com CWP--; 4728975Sandreas.hansson@arm.com else 4738975Sandreas.hansson@arm.com changedCWP = false; 4748975Sandreas.hansson@arm.com 4758975Sandreas.hansson@arm.com if (changedCWP) 4768975Sandreas.hansson@arm.com { 4779087Sandreas.hansson@arm.com CWP = (CWP + NWindows) % NWindows; 4789087Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CWP, CWP); 4799087Sandreas.hansson@arm.com } 4809087Sandreas.hansson@arm.com} 4819087Sandreas.hansson@arm.com 4829087Sandreas.hansson@arm.comvoid getREDVector(MiscReg TT, Addr & PC, Addr & NPC) 4839087Sandreas.hansson@arm.com{ 4848922Swilliam.wang@arm.com //XXX The following constant might belong in a header file. 4858922Swilliam.wang@arm.com const Addr RSTVAddr = 0xFFF0000000ULL; 4862381SN/A PC = RSTVAddr | ((TT << 5) & 0xFF); 487 NPC = PC + sizeof(MachInst); 488} 489 490void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT) 491{ 492 Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA); 493 PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); 494 NPC = PC + sizeof(MachInst); 495} 496 497void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) 498{ 499 Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA); 500 PC = (TBA & ~mask(15)) | 501 (TL > 1 ? (1 << 14) : 0) | 502 ((TT << 5) & mask(14)); 503 NPC = PC + sizeof(MachInst); 504} 505 506#if FULL_SYSTEM 507 508void SparcFaultBase::invoke(ThreadContext * tc) 509{ 510 //panic("Invoking a second fault!\n"); 511 FaultBase::invoke(tc); 512 countStat()++; 513 514 //We can refer to this to see what the trap level -was-, but something 515 //in the middle could change it in the regfile out from under us. 516 MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL); 517 MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT); 518 MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 519 MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 520 521 Addr PC, NPC; 522 523 PrivilegeLevel current; 524 if (hpstate & HPSTATE::hpriv) 525 current = Hyperprivileged; 526 else if (pstate & PSTATE::priv) 527 current = Privileged; 528 else 529 current = User; 530 531 PrivilegeLevel level = getNextLevel(current); 532 533 if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { 534 getREDVector(5, PC, NPC); 535 doREDFault(tc, tt); 536 //This changes the hpstate and pstate, so we need to make sure we 537 //save the old version on the trap stack in doREDFault. 538 enterREDState(tc); 539 } else if (tl == MaxTL) { 540 panic("Should go to error state here.. crap\n"); 541 //Do error_state somehow? 542 //Probably inject a WDR fault using the interrupt mechanism. 543 //What should the PC and NPC be set to? 544 } else if (tl > MaxPTL && level == Privileged) { 545 //guest_watchdog fault 546 doNormalFault(tc, trapType(), true); 547 getHyperVector(tc, PC, NPC, 2); 548 } else if (level == Hyperprivileged || 549 (level == Privileged && trapType() >= 384)) { 550 doNormalFault(tc, trapType(), true); 551 getHyperVector(tc, PC, NPC, trapType()); 552 } else { 553 doNormalFault(tc, trapType(), false); 554 getPrivVector(tc, PC, NPC, trapType(), tl+1); 555 } 556 557 tc->setPC(PC); 558 tc->setNextPC(NPC); 559 tc->setNextNPC(NPC + sizeof(MachInst)); 560} 561 562void PowerOnReset::invoke(ThreadContext * tc) 563{ 564 //For SPARC, when a system is first started, there is a power 565 //on reset Trap which sets the processor into the following state. 566 //Bits that aren't set aren't defined on startup. 567 568 tc->setMiscRegNoEffect(MISCREG_TL, MaxTL); 569 tc->setMiscRegNoEffect(MISCREG_TT, trapType()); 570 tc->setMiscReg(MISCREG_GL, MaxGL); 571 572 //Turn on pef and priv, set everything else to 0 573 tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2)); 574 575 //Turn on red and hpriv, set everything else to 0 576 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 577 //HPSTATE.red = 1 578 HPSTATE |= (1 << 5); 579 //HPSTATE.hpriv = 1 580 HPSTATE |= (1 << 2); 581 //HPSTATE.ibe = 0 582 HPSTATE &= ~(1 << 10); 583 //HPSTATE.tlz = 0 584 HPSTATE &= ~(1 << 0); 585 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 586 587 //The tick register is unreadable by nonprivileged software 588 tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63); 589 590 //Enter RED state. We do this last so that the actual state preserved in 591 //the trap stack is the state from before this fault. 592 enterREDState(tc); 593 594 Addr PC, NPC; 595 getREDVector(trapType(), PC, NPC); 596 tc->setPC(PC); 597 tc->setNextPC(NPC); 598 tc->setNextNPC(NPC + sizeof(MachInst)); 599 600 //These registers are specified as "undefined" after a POR, and they 601 //should have reasonable values after the miscregfile is reset 602 /* 603 // Clear all the soft interrupt bits 604 softint = 0; 605 // disable timer compare interrupts, reset tick_cmpr 606 tc->setMiscRegNoEffect(MISCREG_ 607 tick_cmprFields.int_dis = 1; 608 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 609 stickFields.npt = 1; //The TICK register is unreadable by by !priv 610 stick_cmprFields.int_dis = 1; // disable timer compare interrupts 611 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 612 613 tt[tl] = _trapType; 614 615 hintp = 0; // no interrupts pending 616 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts 617 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 618 */ 619} 620 621#else // !FULL_SYSTEM 622 623void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc) 624{ 625 Process *p = tc->getProcessPtr(); 626 TlbEntry entry; 627 bool success = p->pTable->lookup(vaddr, entry); 628 if(!success) { 629 panic("Tried to execute unmapped address %#x.\n", vaddr); 630 } else { 631 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 632 tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/, 633 p->M5_pid /*context id*/, false, entry.pte); 634 } 635} 636 637void FastDataAccessMMUMiss::invoke(ThreadContext *tc) 638{ 639 Process *p = tc->getProcessPtr(); 640 TlbEntry entry; 641 bool success = p->pTable->lookup(vaddr, entry); 642 if(!success) { 643 p->checkAndAllocNextPage(vaddr); 644 success = p->pTable->lookup(vaddr, entry); 645 } 646 if(!success) { 647 panic("Tried to access unmapped address %#x.\n", vaddr); 648 } else { 649 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 650 tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/, 651 p->M5_pid /*context id*/, false, entry.pte); 652 } 653} 654 655void SpillNNormal::invoke(ThreadContext *tc) 656{ 657 doNormalFault(tc, trapType(), false); 658 659 Process *p = tc->getProcessPtr(); 660 661 //XXX This will only work in faults from a SparcLiveProcess 662 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 663 assert(lp); 664 665 //Then adjust the PC and NPC 666 Addr spillStart = lp->readSpillStart(); 667 tc->setPC(spillStart); 668 tc->setNextPC(spillStart + sizeof(MachInst)); 669 tc->setNextNPC(spillStart + 2*sizeof(MachInst)); 670} 671 672void FillNNormal::invoke(ThreadContext *tc) 673{ 674 doNormalFault(tc, trapType(), false); 675 676 Process * p = tc->getProcessPtr(); 677 678 //XXX This will only work in faults from a SparcLiveProcess 679 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 680 assert(lp); 681 682 //Then adjust the PC and NPC 683 Addr fillStart = lp->readFillStart(); 684 tc->setPC(fillStart); 685 tc->setNextPC(fillStart + sizeof(MachInst)); 686 tc->setNextNPC(fillStart + 2*sizeof(MachInst)); 687} 688 689void TrapInstruction::invoke(ThreadContext *tc) 690{ 691 //In SE, this mechanism is how the process requests a service from the 692 //operating system. We'll get the process object from the thread context 693 //and let it service the request. 694 695 Process *p = tc->getProcessPtr(); 696 697 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 698 assert(lp); 699 700 lp->handleTrap(_n, tc); 701 702 //We need to explicitly advance the pc, since that's not done for us 703 //on a faulting instruction 704 tc->setPC(tc->readNextPC()); 705 tc->setNextPC(tc->readNextNPC()); 706 tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst)); 707} 708 709#endif 710 711} // namespace SparcISA 712 713