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