faults.cc revision 3628
17405SAli.Saidi@ARM.com/* 27405SAli.Saidi@ARM.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 37405SAli.Saidi@ARM.com * All rights reserved. 47405SAli.Saidi@ARM.com * 57405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 67405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 77405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 87405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 97405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 107405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 117405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 127405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 137405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 147405SAli.Saidi@ARM.com * this software without specific prior written permission. 157405SAli.Saidi@ARM.com * 167405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277405SAli.Saidi@ARM.com * 287405SAli.Saidi@ARM.com * Authors: Gabe Black 297405SAli.Saidi@ARM.com * Kevin Lim 307405SAli.Saidi@ARM.com */ 317405SAli.Saidi@ARM.com 327405SAli.Saidi@ARM.com#include <algorithm> 337405SAli.Saidi@ARM.com 347405SAli.Saidi@ARM.com#include "arch/sparc/faults.hh" 357405SAli.Saidi@ARM.com#include "arch/sparc/isa_traits.hh" 367405SAli.Saidi@ARM.com#include "arch/sparc/types.hh" 377405SAli.Saidi@ARM.com#include "base/bitfield.hh" 387405SAli.Saidi@ARM.com#include "base/trace.hh" 397405SAli.Saidi@ARM.com#include "config/full_system.hh" 407405SAli.Saidi@ARM.com#include "cpu/base.hh" 417405SAli.Saidi@ARM.com#include "cpu/thread_context.hh" 427678Sgblack@eecs.umich.edu#if !FULL_SYSTEM 438059SAli.Saidi@ARM.com#include "arch/sparc/process.hh" 447405SAli.Saidi@ARM.com#include "mem/page_table.hh" 457405SAli.Saidi@ARM.com#include "sim/process.hh" 467405SAli.Saidi@ARM.com#endif 477405SAli.Saidi@ARM.com 487427Sgblack@eecs.umich.eduusing namespace std; 497427Sgblack@eecs.umich.edu 507427Sgblack@eecs.umich.edunamespace SparcISA 517427Sgblack@eecs.umich.edu{ 527427Sgblack@eecs.umich.edu 537427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 547427Sgblack@eecs.umich.edu SparcFault<PowerOnReset>::vals = 557427Sgblack@eecs.umich.edu {"power_on_reset", 0x001, 0, {H, H, H}}; 567427Sgblack@eecs.umich.edu 577427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 587427Sgblack@eecs.umich.edu SparcFault<WatchDogReset>::vals = 597427Sgblack@eecs.umich.edu {"watch_dog_reset", 0x002, 120, {H, H, H}}; 607604SGene.Wu@arm.com 617427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 627427Sgblack@eecs.umich.edu SparcFault<ExternallyInitiatedReset>::vals = 637427Sgblack@eecs.umich.edu {"externally_initiated_reset", 0x003, 110, {H, H, H}}; 647427Sgblack@eecs.umich.edu 657427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 667427Sgblack@eecs.umich.edu SparcFault<SoftwareInitiatedReset>::vals = 677427Sgblack@eecs.umich.edu {"software_initiated_reset", 0x004, 130, {SH, SH, H}}; 687427Sgblack@eecs.umich.edu 697427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 707427Sgblack@eecs.umich.edu SparcFault<REDStateException>::vals = 717427Sgblack@eecs.umich.edu {"RED_state_exception", 0x005, 1, {H, H, H}}; 727427Sgblack@eecs.umich.edu 737427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 747427Sgblack@eecs.umich.edu SparcFault<StoreError>::vals = 757427Sgblack@eecs.umich.edu {"store_error", 0x007, 201, {H, H, H}}; 767427Sgblack@eecs.umich.edu 777427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 787427Sgblack@eecs.umich.edu SparcFault<InstructionAccessException>::vals = 797645Sali.saidi@arm.com {"instruction_access_exception", 0x008, 300, {H, H, H}}; 807645Sali.saidi@arm.com 817645Sali.saidi@arm.com//XXX This trap is apparently dropped from ua2005 827645Sali.saidi@arm.com/*template<> SparcFaultBase::FaultVals 837645Sali.saidi@arm.com SparcFault<InstructionAccessMMUMiss>::vals = 847427Sgblack@eecs.umich.edu {"inst_mmu", 0x009, 2, {H, H, H}};*/ 857427Sgblack@eecs.umich.edu 867427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 877427Sgblack@eecs.umich.edu SparcFault<InstructionAccessError>::vals = 887427Sgblack@eecs.umich.edu {"instruction_access_error", 0x00A, 400, {H, H, H}}; 897427Sgblack@eecs.umich.edu 907427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 917427Sgblack@eecs.umich.edu SparcFault<IllegalInstruction>::vals = 927427Sgblack@eecs.umich.edu {"illegal_instruction", 0x010, 620, {H, H, H}}; 937427Sgblack@eecs.umich.edu 947427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 957427Sgblack@eecs.umich.edu SparcFault<PrivilegedOpcode>::vals = 967427Sgblack@eecs.umich.edu {"privileged_opcode", 0x011, 700, {P, SH, SH}}; 977427Sgblack@eecs.umich.edu 987427Sgblack@eecs.umich.edu//XXX This trap is apparently dropped from ua2005 997427Sgblack@eecs.umich.edu/*template<> SparcFaultBase::FaultVals 1007427Sgblack@eecs.umich.edu SparcFault<UnimplementedLDD>::vals = 1017427Sgblack@eecs.umich.edu {"unimp_ldd", 0x012, 6, {H, H, H}};*/ 1027427Sgblack@eecs.umich.edu 1037427Sgblack@eecs.umich.edu//XXX This trap is apparently dropped from ua2005 1047427Sgblack@eecs.umich.edu/*template<> SparcFaultBase::FaultVals 1057427Sgblack@eecs.umich.edu SparcFault<UnimplementedSTD>::vals = 1067427Sgblack@eecs.umich.edu {"unimp_std", 0x013, 6, {H, H, H}};*/ 1077427Sgblack@eecs.umich.edu 1087427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 1097427Sgblack@eecs.umich.edu SparcFault<FpDisabled>::vals = 1107427Sgblack@eecs.umich.edu {"fp_disabled", 0x020, 800, {P, P, H}}; 1117427Sgblack@eecs.umich.edu 1127436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1137436Sdam.sunwoo@arm.com SparcFault<FpExceptionIEEE754>::vals = 1147436Sdam.sunwoo@arm.com {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}}; 1157436Sdam.sunwoo@arm.com 1167436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1177436Sdam.sunwoo@arm.com SparcFault<FpExceptionOther>::vals = 1187436Sdam.sunwoo@arm.com {"fp_exception_other", 0x022, 1110, {P, P, H}}; 1197436Sdam.sunwoo@arm.com 1207436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1217436Sdam.sunwoo@arm.com SparcFault<TagOverflow>::vals = 1227436Sdam.sunwoo@arm.com {"tag_overflow", 0x023, 1400, {P, P, H}}; 1237436Sdam.sunwoo@arm.com 1247436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1257436Sdam.sunwoo@arm.com SparcFault<CleanWindow>::vals = 1267436Sdam.sunwoo@arm.com {"clean_window", 0x024, 1010, {P, P, H}}; 1277436Sdam.sunwoo@arm.com 1287436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1297436Sdam.sunwoo@arm.com SparcFault<DivisionByZero>::vals = 1307436Sdam.sunwoo@arm.com {"division_by_zero", 0x028, 1500, {P, P, H}}; 1317436Sdam.sunwoo@arm.com 1327436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1337436Sdam.sunwoo@arm.com SparcFault<InternalProcessorError>::vals = 1347436Sdam.sunwoo@arm.com {"internal_processor_error", 0x029, 4, {H, H, H}}; 1357436Sdam.sunwoo@arm.com 1367436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1377436Sdam.sunwoo@arm.com SparcFault<InstructionInvalidTSBEntry>::vals = 1387436Sdam.sunwoo@arm.com {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}}; 1397436Sdam.sunwoo@arm.com 1407436Sdam.sunwoo@arm.comtemplate<> SparcFaultBase::FaultVals 1417436Sdam.sunwoo@arm.com SparcFault<DataInvalidTSBEntry>::vals = 1427436Sdam.sunwoo@arm.com {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}}; 1437436Sdam.sunwoo@arm.com 1447644Sali.saidi@arm.comtemplate<> SparcFaultBase::FaultVals 1457644Sali.saidi@arm.com SparcFault<DataAccessException>::vals = 1468147SAli.Saidi@ARM.com {"data_access_exception", 0x030, 1201, {H, H, H}}; 1478147SAli.Saidi@ARM.com 1488147SAli.Saidi@ARM.com//XXX This trap is apparently dropped from ua2005 1498147SAli.Saidi@ARM.com/*template<> SparcFaultBase::FaultVals 1508147SAli.Saidi@ARM.com SparcFault<DataAccessMMUMiss>::vals = 1518147SAli.Saidi@ARM.com {"data_mmu", 0x031, 12, {H, H, H}};*/ 1528147SAli.Saidi@ARM.com 1538147SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 1548147SAli.Saidi@ARM.com SparcFault<DataAccessError>::vals = 1558147SAli.Saidi@ARM.com {"data_access_error", 0x032, 1210, {H, H, H}}; 1567427Sgblack@eecs.umich.edu 1577427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 1587427Sgblack@eecs.umich.edu SparcFault<DataAccessProtection>::vals = 1597405SAli.Saidi@ARM.com {"data_access_protection", 0x033, 1207, {H, H, H}}; 1607405SAli.Saidi@ARM.com 1617405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 1627405SAli.Saidi@ARM.com SparcFault<MemAddressNotAligned>::vals = 1637614Sminkyu.jeong@arm.com {"mem_address_not_aligned", 0x034, 1020, {H, H, H}}; 1647614Sminkyu.jeong@arm.com 1657614Sminkyu.jeong@arm.comtemplate<> SparcFaultBase::FaultVals 1667614Sminkyu.jeong@arm.com SparcFault<LDDFMemAddressNotAligned>::vals = 1677614Sminkyu.jeong@arm.com {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}}; 1687614Sminkyu.jeong@arm.com 1697614Sminkyu.jeong@arm.comtemplate<> SparcFaultBase::FaultVals 1707614Sminkyu.jeong@arm.com SparcFault<STDFMemAddressNotAligned>::vals = 1717614Sminkyu.jeong@arm.com {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}}; 1727614Sminkyu.jeong@arm.com 1737614Sminkyu.jeong@arm.comtemplate<> SparcFaultBase::FaultVals 1747405SAli.Saidi@ARM.com SparcFault<PrivilegedAction>::vals = 1757405SAli.Saidi@ARM.com {"privileged_action", 0x037, 1110, {H, H, SH}}; 1767405SAli.Saidi@ARM.com 1777405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 1787405SAli.Saidi@ARM.com SparcFault<LDQFMemAddressNotAligned>::vals = 1797405SAli.Saidi@ARM.com {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}}; 1807405SAli.Saidi@ARM.com 1817405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 1827720Sgblack@eecs.umich.edu SparcFault<STQFMemAddressNotAligned>::vals = 1837720Sgblack@eecs.umich.edu {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}}; 1847720Sgblack@eecs.umich.edu 1857405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 1867405SAli.Saidi@ARM.com SparcFault<InstructionRealTranslationMiss>::vals = 1877757SAli.Saidi@ARM.com {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}}; 1887405SAli.Saidi@ARM.com 1897405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 1907757SAli.Saidi@ARM.com SparcFault<DataRealTranslationMiss>::vals = 1917405SAli.Saidi@ARM.com {"data_real_translation_miss", 0x03F, 1203, {H, H, H}}; 1927405SAli.Saidi@ARM.com 1937731SAli.Saidi@ARM.com//XXX This trap is apparently dropped from ua2005 1947405SAli.Saidi@ARM.com/*template<> SparcFaultBase::FaultVals 1957405SAli.Saidi@ARM.com SparcFault<AsyncDataError>::vals = 1967731SAli.Saidi@ARM.com {"async_data", 0x040, 2, {H, H, H}};*/ 1977405SAli.Saidi@ARM.com 1987405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 1997405SAli.Saidi@ARM.com SparcFault<InterruptLevelN>::vals = 2007588SAli.Saidi@arm.com {"interrupt_level_n", 0x041, 0, {P, P, SH}}; 2017588SAli.Saidi@arm.com 2027588SAli.Saidi@arm.comtemplate<> SparcFaultBase::FaultVals 2037583SAli.Saidi@arm.com SparcFault<HstickMatch>::vals = 2047583SAli.Saidi@arm.com {"hstick_match", 0x05E, 1601, {H, H, H}}; 2057583SAli.Saidi@arm.com 2067583SAli.Saidi@arm.comtemplate<> SparcFaultBase::FaultVals 2077583SAli.Saidi@arm.com SparcFault<TrapLevelZero>::vals = 2087583SAli.Saidi@arm.com {"trap_level_zero", 0x05F, 202, {H, H, SH}}; 2097583SAli.Saidi@arm.com 2107583SAli.Saidi@arm.comtemplate<> SparcFaultBase::FaultVals 2117583SAli.Saidi@arm.com SparcFault<PAWatchpoint>::vals = 2127583SAli.Saidi@arm.com {"PA_watchpoint", 0x061, 1209, {H, H, H}}; 2137583SAli.Saidi@arm.com 2147583SAli.Saidi@arm.comtemplate<> SparcFaultBase::FaultVals 2157583SAli.Saidi@arm.com SparcFault<VAWatchpoint>::vals = 2167783SGiacomo.Gabrielli@arm.com {"VA_watchpoint", 0x062, 1120, {P, P, SH}}; 2177783SGiacomo.Gabrielli@arm.com 2187783SGiacomo.Gabrielli@arm.comtemplate<> SparcFaultBase::FaultVals 2197783SGiacomo.Gabrielli@arm.com SparcFault<FastInstructionAccessMMUMiss>::vals = 2207405SAli.Saidi@ARM.com {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}}; 2217405SAli.Saidi@ARM.com 2227405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 2237405SAli.Saidi@ARM.com SparcFault<FastDataAccessMMUMiss>::vals = 2247405SAli.Saidi@ARM.com {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}}; 2257405SAli.Saidi@ARM.com 2267405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 2277405SAli.Saidi@ARM.com SparcFault<FastDataAccessProtection>::vals = 2287614Sminkyu.jeong@arm.com {"fast_data_access_protection", 0x06C, 1207, {H, H, H}}; 2297614Sminkyu.jeong@arm.com 2307614Sminkyu.jeong@arm.comtemplate<> SparcFaultBase::FaultVals 2317614Sminkyu.jeong@arm.com SparcFault<InstructionBreakpoint>::vals = 2327614Sminkyu.jeong@arm.com {"instruction_break", 0x076, 610, {H, H, H}}; 2337614Sminkyu.jeong@arm.com 2347614Sminkyu.jeong@arm.comtemplate<> SparcFaultBase::FaultVals 2357614Sminkyu.jeong@arm.com SparcFault<CpuMondo>::vals = 2367614Sminkyu.jeong@arm.com {"cpu_mondo", 0x07C, 1608, {P, P, SH}}; 2377614Sminkyu.jeong@arm.com 2387405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 2397405SAli.Saidi@ARM.com SparcFault<DevMondo>::vals = 2407405SAli.Saidi@ARM.com {"dev_mondo", 0x07D, 1611, {P, P, SH}}; 2417405SAli.Saidi@ARM.com 2427405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 2437749SAli.Saidi@ARM.com SparcFault<ResumeableError>::vals = 2447405SAli.Saidi@ARM.com {"resume_error", 0x07E, 3330, {P, P, SH}}; 2457405SAli.Saidi@ARM.com 2467405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 2477749SAli.Saidi@ARM.com SparcFault<SpillNNormal>::vals = 2487749SAli.Saidi@ARM.com {"spill_n_normal", 0x080, 900, {P, P, H}}; 2497749SAli.Saidi@ARM.com 2507749SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 2517405SAli.Saidi@ARM.com SparcFault<SpillNOther>::vals = 2527749SAli.Saidi@ARM.com {"spill_n_other", 0x0A0, 900, {P, P, H}}; 2537749SAli.Saidi@ARM.com 2547749SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 2557749SAli.Saidi@ARM.com SparcFault<FillNNormal>::vals = 2567749SAli.Saidi@ARM.com {"fill_n_normal", 0x0C0, 900, {P, P, H}}; 2577614Sminkyu.jeong@arm.com 2587614Sminkyu.jeong@arm.comtemplate<> SparcFaultBase::FaultVals 2597720Sgblack@eecs.umich.edu SparcFault<FillNOther>::vals = 2607720Sgblack@eecs.umich.edu {"fill_n_other", 0x0E0, 900, {P, P, H}}; 2617720Sgblack@eecs.umich.edu 2627720Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 2637408Sgblack@eecs.umich.edu SparcFault<TrapInstruction>::vals = 2647405SAli.Saidi@ARM.com {"trap_instruction", 0x100, 1602, {P, P, H}}; 2657405SAli.Saidi@ARM.com 2667405SAli.Saidi@ARM.com#if !FULL_SYSTEM 2677408Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 2687408Sgblack@eecs.umich.edu SparcFault<PageTableFault>::vals = 2697408Sgblack@eecs.umich.edu {"page_table_fault", 0x0000, 0, {SH, SH, SH}}; 2707408Sgblack@eecs.umich.edu#endif 2718206SWilliam.Wang@arm.com 2728206SWilliam.Wang@arm.com/** 2738206SWilliam.Wang@arm.com * This causes the thread context to enter RED state. This causes the side 2748206SWilliam.Wang@arm.com * effects which go with entering RED state because of a trap. 2758206SWilliam.Wang@arm.com */ 2768206SWilliam.Wang@arm.com 2778206SWilliam.Wang@arm.comvoid enterREDState(ThreadContext *tc) 2788206SWilliam.Wang@arm.com{ 2798206SWilliam.Wang@arm.com //@todo Disable the mmu? 2808206SWilliam.Wang@arm.com //@todo Disable watchpoints? 2818206SWilliam.Wang@arm.com MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); 2827408Sgblack@eecs.umich.edu //HPSTATE.red = 1 2837408Sgblack@eecs.umich.edu HPSTATE |= (1 << 5); 2847408Sgblack@eecs.umich.edu //HPSTATE.hpriv = 1 2857731SAli.Saidi@ARM.com HPSTATE |= (1 << 2); 2868206SWilliam.Wang@arm.com tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE); 2877408Sgblack@eecs.umich.edu} 2887408Sgblack@eecs.umich.edu 2897408Sgblack@eecs.umich.edu/** 2907408Sgblack@eecs.umich.edu * This sets everything up for a RED state trap except for actually jumping to 2917408Sgblack@eecs.umich.edu * the handler. 2927408Sgblack@eecs.umich.edu */ 2937408Sgblack@eecs.umich.edu 2947408Sgblack@eecs.umich.eduvoid doREDFault(ThreadContext *tc, TrapType tt) 2957408Sgblack@eecs.umich.edu{ 2967408Sgblack@eecs.umich.edu MiscReg TL = tc->readMiscReg(MISCREG_TL); 2977408Sgblack@eecs.umich.edu MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); 2987408Sgblack@eecs.umich.edu MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); 2997408Sgblack@eecs.umich.edu MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); 3007408Sgblack@eecs.umich.edu MiscReg CCR = tc->readMiscReg(MISCREG_CCR); 3017408Sgblack@eecs.umich.edu MiscReg ASI = tc->readMiscReg(MISCREG_ASI); 3027408Sgblack@eecs.umich.edu MiscReg CWP = tc->readMiscReg(MISCREG_CWP); 3037408Sgblack@eecs.umich.edu MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); 3047408Sgblack@eecs.umich.edu MiscReg GL = tc->readMiscReg(MISCREG_GL); 3057408Sgblack@eecs.umich.edu MiscReg PC = tc->readPC(); 3067408Sgblack@eecs.umich.edu MiscReg NPC = tc->readNextPC(); 3077408Sgblack@eecs.umich.edu 3087408Sgblack@eecs.umich.edu TL++; 3097408Sgblack@eecs.umich.edu 3107408Sgblack@eecs.umich.edu //set TSTATE.gl to gl 3117408Sgblack@eecs.umich.edu replaceBits(TSTATE, 42, 40, GL); 3127783SGiacomo.Gabrielli@arm.com //set TSTATE.ccr to ccr 3137783SGiacomo.Gabrielli@arm.com replaceBits(TSTATE, 39, 32, CCR); 3147783SGiacomo.Gabrielli@arm.com //set TSTATE.asi to asi 3157783SGiacomo.Gabrielli@arm.com replaceBits(TSTATE, 31, 24, ASI); 3167783SGiacomo.Gabrielli@arm.com //set TSTATE.pstate to pstate 3177783SGiacomo.Gabrielli@arm.com replaceBits(TSTATE, 20, 8, PSTATE); 3187783SGiacomo.Gabrielli@arm.com //set TSTATE.cwp to cwp 3197783SGiacomo.Gabrielli@arm.com replaceBits(TSTATE, 4, 0, CWP); 3207783SGiacomo.Gabrielli@arm.com 3217783SGiacomo.Gabrielli@arm.com //Write back TSTATE 3227783SGiacomo.Gabrielli@arm.com tc->setMiscReg(MISCREG_TSTATE, TSTATE); 3237783SGiacomo.Gabrielli@arm.com 3247408Sgblack@eecs.umich.edu //set TPC to PC 3257408Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TPC, PC); 3268206SWilliam.Wang@arm.com //set TNPC to NPC 3278206SWilliam.Wang@arm.com tc->setMiscReg(MISCREG_TNPC, NPC); 3287408Sgblack@eecs.umich.edu 3297408Sgblack@eecs.umich.edu //set HTSTATE.hpstate to hpstate 3307408Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 3317408Sgblack@eecs.umich.edu 3327408Sgblack@eecs.umich.edu //TT = trap type; 3337408Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TT, tt); 3347408Sgblack@eecs.umich.edu 3357408Sgblack@eecs.umich.edu //Update GL 3367408Sgblack@eecs.umich.edu tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); 3377408Sgblack@eecs.umich.edu 3387408Sgblack@eecs.umich.edu //set PSTATE.mm to 00 3397408Sgblack@eecs.umich.edu //set PSTATE.pef to 1 3407749SAli.Saidi@ARM.com PSTATE |= (1 << 4); 3417749SAli.Saidi@ARM.com //set PSTATE.am to 0 3427408Sgblack@eecs.umich.edu PSTATE &= ~(1 << 3); 3437408Sgblack@eecs.umich.edu //set PSTATE.priv to 0 3447408Sgblack@eecs.umich.edu PSTATE &= ~(1 << 2); 3457408Sgblack@eecs.umich.edu //set PSTATE.ie to 0 3467408Sgblack@eecs.umich.edu PSTATE &= ~(1 << 1); 3477408Sgblack@eecs.umich.edu //set PSTATE.cle to 0 3487408Sgblack@eecs.umich.edu PSTATE &= ~(1 << 9); 3497408Sgblack@eecs.umich.edu //PSTATE.tle is unchanged 3507408Sgblack@eecs.umich.edu //XXX Where is the tct bit? 3517408Sgblack@eecs.umich.edu //set PSTATE.tct to 0 3527731SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_PSTATE, PSTATE); 3537408Sgblack@eecs.umich.edu 3547408Sgblack@eecs.umich.edu //set HPSTATE.red to 1 3557408Sgblack@eecs.umich.edu HPSTATE |= (1 << 5); 3567408Sgblack@eecs.umich.edu //set HPSTATE.hpriv to 1 3577408Sgblack@eecs.umich.edu HPSTATE |= (1 << 2); 3587408Sgblack@eecs.umich.edu //set HPSTATE.ibe to 0 3597408Sgblack@eecs.umich.edu HPSTATE &= ~(1 << 10); 3607408Sgblack@eecs.umich.edu //set HPSTATE.tlz to 0 3617408Sgblack@eecs.umich.edu HPSTATE &= ~(1 << 0); 3627408Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); 3637408Sgblack@eecs.umich.edu 3647731SAli.Saidi@ARM.com bool changedCWP = true; 3657408Sgblack@eecs.umich.edu if(tt == 0x24) 3667408Sgblack@eecs.umich.edu CWP++; 3677408Sgblack@eecs.umich.edu else if(0x80 <= tt && tt <= 0xbf) 3687408Sgblack@eecs.umich.edu CWP += (CANSAVE + 2); 3697408Sgblack@eecs.umich.edu else if(0xc0 <= tt && tt <= 0xff) 3707408Sgblack@eecs.umich.edu CWP--; 3717408Sgblack@eecs.umich.edu else 3727731SAli.Saidi@ARM.com changedCWP = false; 3737408Sgblack@eecs.umich.edu 3747408Sgblack@eecs.umich.edu if(changedCWP) 3757408Sgblack@eecs.umich.edu { 3767408Sgblack@eecs.umich.edu CWP = (CWP + NWindows) % NWindows; 3777408Sgblack@eecs.umich.edu tc->setMiscRegWithEffect(MISCREG_CWP, CWP); 3787731SAli.Saidi@ARM.com } 3797408Sgblack@eecs.umich.edu} 3807408Sgblack@eecs.umich.edu 3817408Sgblack@eecs.umich.edu/** 3827408Sgblack@eecs.umich.edu * This sets everything up for a normal trap except for actually jumping to 3837408Sgblack@eecs.umich.edu * the handler. 3847408Sgblack@eecs.umich.edu */ 3857408Sgblack@eecs.umich.edu 3867408Sgblack@eecs.umich.eduvoid doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) 3877408Sgblack@eecs.umich.edu{ 3887408Sgblack@eecs.umich.edu MiscReg TL = tc->readMiscReg(MISCREG_TL); 3897408Sgblack@eecs.umich.edu MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); 3907408Sgblack@eecs.umich.edu MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); 3917408Sgblack@eecs.umich.edu MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); 3927408Sgblack@eecs.umich.edu MiscReg CCR = tc->readMiscReg(MISCREG_CCR); 3937408Sgblack@eecs.umich.edu MiscReg ASI = tc->readMiscReg(MISCREG_ASI); 3947408Sgblack@eecs.umich.edu MiscReg CWP = tc->readMiscReg(MISCREG_CWP); 3957405SAli.Saidi@ARM.com MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); 3967583SAli.Saidi@arm.com MiscReg GL = tc->readMiscReg(MISCREG_GL); 3977583SAli.Saidi@arm.com MiscReg PC = tc->readPC(); 3987583SAli.Saidi@arm.com MiscReg NPC = tc->readNextPC(); 3997583SAli.Saidi@arm.com 4008059SAli.Saidi@ARM.com //Increment the trap level 4018059SAli.Saidi@ARM.com TL++; 4028059SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_TL, TL); 4038059SAli.Saidi@ARM.com 4048059SAli.Saidi@ARM.com //Save off state 4058059SAli.Saidi@ARM.com 4068059SAli.Saidi@ARM.com //set TSTATE.gl to gl 4078059SAli.Saidi@ARM.com replaceBits(TSTATE, 42, 40, GL); 4088059SAli.Saidi@ARM.com //set TSTATE.ccr to ccr 4098059SAli.Saidi@ARM.com replaceBits(TSTATE, 39, 32, CCR); 4108059SAli.Saidi@ARM.com //set TSTATE.asi to asi 4118059SAli.Saidi@ARM.com replaceBits(TSTATE, 31, 24, ASI); 4127583SAli.Saidi@arm.com //set TSTATE.pstate to pstate 4137583SAli.Saidi@arm.com replaceBits(TSTATE, 20, 8, PSTATE); 4147583SAli.Saidi@arm.com //set TSTATE.cwp to cwp 4157583SAli.Saidi@arm.com replaceBits(TSTATE, 4, 0, CWP); 4167583SAli.Saidi@arm.com 4177436Sdam.sunwoo@arm.com //Write back TSTATE 4187436Sdam.sunwoo@arm.com tc->setMiscReg(MISCREG_TSTATE, TSTATE); 4197436Sdam.sunwoo@arm.com 4207436Sdam.sunwoo@arm.com //set TPC to PC 4217436Sdam.sunwoo@arm.com tc->setMiscReg(MISCREG_TPC, PC); 4227436Sdam.sunwoo@arm.com //set TNPC to NPC 4237436Sdam.sunwoo@arm.com tc->setMiscReg(MISCREG_TNPC, NPC); 4247436Sdam.sunwoo@arm.com 4257436Sdam.sunwoo@arm.com //set HTSTATE.hpstate to hpstate 4267436Sdam.sunwoo@arm.com tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 4277436Sdam.sunwoo@arm.com 4287436Sdam.sunwoo@arm.com //TT = trap type; 4297436Sdam.sunwoo@arm.com tc->setMiscReg(MISCREG_TT, tt); 4307436Sdam.sunwoo@arm.com 4317436Sdam.sunwoo@arm.com //Update the global register level 4327436Sdam.sunwoo@arm.com if(!gotoHpriv) 4337436Sdam.sunwoo@arm.com tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL)); 4347436Sdam.sunwoo@arm.com else 4357436Sdam.sunwoo@arm.com tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); 4367436Sdam.sunwoo@arm.com 4377436Sdam.sunwoo@arm.com //PSTATE.mm is unchanged 4387436Sdam.sunwoo@arm.com //PSTATE.pef = whether or not an fpu is present 4397436Sdam.sunwoo@arm.com //XXX We'll say there's one present, even though there aren't 4407436Sdam.sunwoo@arm.com //implementations for a decent number of the instructions 4417436Sdam.sunwoo@arm.com PSTATE |= (1 << 4); 4427436Sdam.sunwoo@arm.com //PSTATE.am = 0 4437436Sdam.sunwoo@arm.com PSTATE &= ~(1 << 3); 4447436Sdam.sunwoo@arm.com if(!gotoHpriv) 4457436Sdam.sunwoo@arm.com { 4467436Sdam.sunwoo@arm.com //PSTATE.priv = 1 4477442Ssaidi@eecs.umich.edu PSTATE |= (1 << 2); 4487436Sdam.sunwoo@arm.com //PSTATE.cle = PSTATE.tle 4497436Sdam.sunwoo@arm.com replaceBits(PSTATE, 9, 9, PSTATE >> 8); 4508208SAli.Saidi@ARM.com } 4517720Sgblack@eecs.umich.edu else 4527436Sdam.sunwoo@arm.com { 4537436Sdam.sunwoo@arm.com //PSTATE.priv = 0 4547436Sdam.sunwoo@arm.com PSTATE &= ~(1 << 2); 4557436Sdam.sunwoo@arm.com //PSTATE.cle = 0 4567436Sdam.sunwoo@arm.com PSTATE &= ~(1 << 9); 4577436Sdam.sunwoo@arm.com } 4587436Sdam.sunwoo@arm.com //PSTATE.ie = 0 4597436Sdam.sunwoo@arm.com PSTATE &= ~(1 << 1); 4607436Sdam.sunwoo@arm.com //PSTATE.tle is unchanged 4617436Sdam.sunwoo@arm.com //PSTATE.tct = 0 4627436Sdam.sunwoo@arm.com //XXX Where exactly is this field? 4637436Sdam.sunwoo@arm.com tc->setMiscReg(MISCREG_PSTATE, PSTATE); 4647436Sdam.sunwoo@arm.com 4657436Sdam.sunwoo@arm.com if(gotoHpriv) 4667436Sdam.sunwoo@arm.com { 4677436Sdam.sunwoo@arm.com //HPSTATE.red = 0 4687436Sdam.sunwoo@arm.com HPSTATE &= ~(1 << 5); 4697436Sdam.sunwoo@arm.com //HPSTATE.hpriv = 1 4707436Sdam.sunwoo@arm.com HPSTATE |= (1 << 2); 4717436Sdam.sunwoo@arm.com //HPSTATE.ibe = 0 4727749SAli.Saidi@ARM.com HPSTATE &= ~(1 << 10); 4737749SAli.Saidi@ARM.com //HPSTATE.tlz is unchanged 4747749SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); 4757749SAli.Saidi@ARM.com } 4767749SAli.Saidi@ARM.com 4777749SAli.Saidi@ARM.com bool changedCWP = true; 4787749SAli.Saidi@ARM.com if(tt == 0x24) 4798208SAli.Saidi@ARM.com CWP++; 4808208SAli.Saidi@ARM.com else if(0x80 <= tt && tt <= 0xbf) 4818208SAli.Saidi@ARM.com CWP += (CANSAVE + 2); 4828208SAli.Saidi@ARM.com else if(0xc0 <= tt && tt <= 0xff) 4838208SAli.Saidi@ARM.com CWP--; 4848208SAli.Saidi@ARM.com else 4858208SAli.Saidi@ARM.com changedCWP = false; 4867405SAli.Saidi@ARM.com 4877405SAli.Saidi@ARM.com if(changedCWP) 4887405SAli.Saidi@ARM.com { 4897405SAli.Saidi@ARM.com CWP = (CWP + NWindows) % NWindows; 4907405SAli.Saidi@ARM.com tc->setMiscRegWithEffect(MISCREG_CWP, CWP); 4917405SAli.Saidi@ARM.com } 492} 493 494void getREDVector(MiscReg TT, Addr & PC, Addr & NPC) 495{ 496 //XXX The following constant might belong in a header file. 497 const Addr RSTVAddr = 0xFFF0000000ULL; 498 PC = RSTVAddr | ((TT << 5) & 0xFF); 499 NPC = PC + sizeof(MachInst); 500} 501 502void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT) 503{ 504 Addr HTBA = tc->readMiscReg(MISCREG_HTBA); 505 PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); 506 NPC = PC + sizeof(MachInst); 507} 508 509void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) 510{ 511 Addr TBA = tc->readMiscReg(MISCREG_TBA); 512 PC = (TBA & ~mask(15)) | 513 (TL > 1 ? (1 << 14) : 0) | 514 ((TT << 5) & mask(14)); 515 NPC = PC + sizeof(MachInst); 516} 517 518#if FULL_SYSTEM 519 520void SparcFaultBase::invoke(ThreadContext * tc) 521{ 522 panic("Invoking a second fault!\n"); 523 FaultBase::invoke(tc); 524 countStat()++; 525 526 //We can refer to this to see what the trap level -was-, but something 527 //in the middle could change it in the regfile out from under us. 528 MiscReg TL = tc->readMiscReg(MISCREG_TL); 529 MiscReg TT = tc->readMiscReg(MISCREG_TT); 530 MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); 531 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); 532 533 Addr PC, NPC; 534 535 PrivilegeLevel current; 536 if(!(PSTATE & (1 << 2))) 537 current = User; 538 else if(!(HPSTATE & (1 << 2))) 539 current = Privileged; 540 else 541 current = Hyperprivileged; 542 543 PrivilegeLevel level = getNextLevel(current); 544 545 if(HPSTATE & (1 << 5) || TL == MaxTL - 1) 546 { 547 getREDVector(5, PC, NPC); 548 enterREDState(tc); 549 doREDFault(tc, TT); 550 } 551 else if(TL == MaxTL) 552 { 553 //Do error_state somehow? 554 //Probably inject a WDR fault using the interrupt mechanism. 555 //What should the PC and NPC be set to? 556 } 557 else if(TL > MaxPTL && level == Privileged) 558 { 559 //guest_watchdog fault 560 doNormalFault(tc, trapType(), true); 561 getHyperVector(tc, PC, NPC, 2); 562 } 563 else if(level == Hyperprivileged) 564 { 565 doNormalFault(tc, trapType(), true); 566 getHyperVector(tc, PC, NPC, trapType()); 567 } 568 else 569 { 570 doNormalFault(tc, trapType(), false); 571 getPrivVector(tc, PC, NPC, trapType(), TL+1); 572 } 573 574 tc->setPC(PC); 575 tc->setNextPC(NPC); 576 tc->setNextNPC(NPC + sizeof(MachInst)); 577} 578 579void PowerOnReset::invoke(ThreadContext * tc) 580{ 581 //First, enter RED state. 582 enterREDState(tc); 583 584 //For SPARC, when a system is first started, there is a power 585 //on reset Trap which sets the processor into the following state. 586 //Bits that aren't set aren't defined on startup. 587 588 tc->setMiscReg(MISCREG_TL, MaxTL); 589 tc->setMiscReg(MISCREG_TT, trapType()); 590 tc->setMiscRegWithEffect(MISCREG_GL, MaxGL); 591 592 //Turn on pef, set everything else to 0 593 tc->setMiscReg(MISCREG_PSTATE, 1 << 4); 594 595 //Turn on red and hpriv, set everything else to 0 596 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); 597 //HPSTATE.red = 1 598 HPSTATE |= (1 << 5); 599 //HPSTATE.hpriv = 1 600 HPSTATE |= (1 << 2); 601 //HPSTATE.ibe = 0 602 HPSTATE &= ~(1 << 10); 603 //HPSTATE.tlz = 0 604 HPSTATE &= ~(1 << 0); 605 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); 606 607 //The tick register is unreadable by nonprivileged software 608 tc->setMiscReg(MISCREG_TICK, 1ULL << 63); 609 610 Addr PC, NPC; 611 getREDVector(trapType(), PC, NPC); 612 tc->setPC(PC); 613 tc->setNextPC(NPC); 614 tc->setNextNPC(NPC + sizeof(MachInst)); 615 616 //These registers are specified as "undefined" after a POR, and they 617 //should have reasonable values after the miscregfile is reset 618 /* 619 // Clear all the soft interrupt bits 620 softint = 0; 621 // disable timer compare interrupts, reset tick_cmpr 622 tc->setMiscReg(MISCREG_ 623 tick_cmprFields.int_dis = 1; 624 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 625 stickFields.npt = 1; //The TICK register is unreadable by by !priv 626 stick_cmprFields.int_dis = 1; // disable timer compare interrupts 627 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 628 629 tt[tl] = _trapType; 630 631 hintp = 0; // no interrupts pending 632 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts 633 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 634 */ 635} 636 637#else // !FULL_SYSTEM 638 639void SpillNNormal::invoke(ThreadContext *tc) 640{ 641 doNormalFault(tc, trapType(), false); 642 643 Process *p = tc->getProcessPtr(); 644 645 //XXX This will only work in faults from a SparcLiveProcess 646 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 647 assert(lp); 648 649 //Then adjust the PC and NPC 650 Addr spillStart = lp->readSpillStart(); 651 tc->setPC(spillStart); 652 tc->setNextPC(spillStart + sizeof(MachInst)); 653 tc->setNextNPC(spillStart + 2*sizeof(MachInst)); 654} 655 656void FillNNormal::invoke(ThreadContext *tc) 657{ 658 doNormalFault(tc, trapType(), false); 659 660 Process * p = tc->getProcessPtr(); 661 662 //XXX This will only work in faults from a SparcLiveProcess 663 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 664 assert(lp); 665 666 //Then adjust the PC and NPC 667 Addr fillStart = lp->readFillStart(); 668 tc->setPC(fillStart); 669 tc->setNextPC(fillStart + sizeof(MachInst)); 670 tc->setNextNPC(fillStart + 2*sizeof(MachInst)); 671} 672 673void PageTableFault::invoke(ThreadContext *tc) 674{ 675 Process *p = tc->getProcessPtr(); 676 677 // address is higher than the stack region or in the current stack region 678 if (vaddr > p->stack_base || vaddr > p->stack_min) 679 FaultBase::invoke(tc); 680 681 // We've accessed the next page 682 if (vaddr > p->stack_min - PageBytes) { 683 p->stack_min -= PageBytes; 684 if (p->stack_base - p->stack_min > 8*1024*1024) 685 fatal("Over max stack size for one thread\n"); 686 p->pTable->allocate(p->stack_min, PageBytes); 687 warn("Increasing stack size by one page."); 688 } else { 689 FaultBase::invoke(tc); 690 } 691} 692 693#endif 694 695} // namespace SparcISA 696 697