faults.cc revision 11851
17405SAli.Saidi@ARM.com/* 211573SDylan.Johnson@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 "arch/sparc/faults.hh" 337405SAli.Saidi@ARM.com 347405SAli.Saidi@ARM.com#include <algorithm> 357405SAli.Saidi@ARM.com 367405SAli.Saidi@ARM.com#include "arch/sparc/isa_traits.hh" 377405SAli.Saidi@ARM.com#include "arch/sparc/process.hh" 387405SAli.Saidi@ARM.com#include "arch/sparc/types.hh" 397405SAli.Saidi@ARM.com#include "base/bitfield.hh" 407405SAli.Saidi@ARM.com#include "base/trace.hh" 417405SAli.Saidi@ARM.com#include "cpu/base.hh" 4211793Sbrandon.potter@amd.com#include "cpu/thread_context.hh" 4310461SAndreas.Sandberg@ARM.com#include "mem/page_table.hh" 449050Schander.sudanthi@arm.com#include "sim/full_system.hh" 4511793Sbrandon.potter@amd.com#include "sim/process.hh" 468887Sgeoffrey.blake@arm.com 478232Snate@binkert.orgusing namespace std; 488232Snate@binkert.org 4910844Sandreas.sandberg@arm.comnamespace SparcISA 509384SAndreas.Sandberg@arm.com{ 517678Sgblack@eecs.umich.edu 528059SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 538284SAli.Saidi@ARM.com SparcFault<PowerOnReset>::vals = 547405SAli.Saidi@ARM.com{"power_on_reset", 0x001, 0, {H, H, H}, FaultStat()}; 557405SAli.Saidi@ARM.com 567405SAli.Saidi@ARM.comtemplate<> SparcFaultBase::FaultVals 577405SAli.Saidi@ARM.com SparcFault<WatchDogReset>::vals = 5810037SARM gem5 Developers{"watch_dog_reset", 0x002, 120, {H, H, H}, FaultStat()}; 5910037SARM gem5 Developers 6011768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 6110037SARM gem5 Developers SparcFault<ExternallyInitiatedReset>::vals = 6210037SARM gem5 Developers{"externally_initiated_reset", 0x003, 110, {H, H, H}, FaultStat()}; 6310037SARM gem5 Developers 6410037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 6511768SCurtis.Dunham@arm.com SparcFault<SoftwareInitiatedReset>::vals = 6610037SARM gem5 Developers{"software_initiated_reset", 0x004, 130, {SH, SH, H}, FaultStat()}; 6710037SARM gem5 Developers 6811768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 6911768SCurtis.Dunham@arm.com SparcFault<REDStateException>::vals = 7011768SCurtis.Dunham@arm.com{"RED_state_exception", 0x005, 1, {H, H, H}, FaultStat()}; 7111768SCurtis.Dunham@arm.com 7211768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 7311768SCurtis.Dunham@arm.com SparcFault<StoreError>::vals = 7411768SCurtis.Dunham@arm.com{"store_error", 0x007, 201, {H, H, H}, FaultStat()}; 7511768SCurtis.Dunham@arm.com 7611768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 7711768SCurtis.Dunham@arm.com SparcFault<InstructionAccessException>::vals = 7811768SCurtis.Dunham@arm.com{"instruction_access_exception", 0x008, 300, {H, H, H}, FaultStat()}; 7911768SCurtis.Dunham@arm.com 8010037SARM gem5 Developers//XXX This trap is apparently dropped from ua2005 8110037SARM gem5 Developers/*template<> SparcFaultBase::FaultVals 8210037SARM gem5 Developers SparcFault<InstructionAccessMMUMiss>::vals = 8311768SCurtis.Dunham@arm.com {"inst_mmu", 0x009, 2, {H, H, H}};*/ 8411768SCurtis.Dunham@arm.com 8511768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 8611768SCurtis.Dunham@arm.com SparcFault<InstructionAccessError>::vals = 8711768SCurtis.Dunham@arm.com{"instruction_access_error", 0x00A, 400, {H, H, H}, FaultStat()}; 8811768SCurtis.Dunham@arm.com 8911768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 9011768SCurtis.Dunham@arm.com SparcFault<IllegalInstruction>::vals = 9110037SARM gem5 Developers{"illegal_instruction", 0x010, 620, {H, H, H}, FaultStat()}; 9211768SCurtis.Dunham@arm.com 9311768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 9411768SCurtis.Dunham@arm.com SparcFault<PrivilegedOpcode>::vals = 9511768SCurtis.Dunham@arm.com{"privileged_opcode", 0x011, 700, {P, SH, SH}, FaultStat()}; 9610037SARM gem5 Developers 9711768SCurtis.Dunham@arm.com//XXX This trap is apparently dropped from ua2005 9811768SCurtis.Dunham@arm.com/*template<> SparcFaultBase::FaultVals 9911768SCurtis.Dunham@arm.com SparcFault<UnimplementedLDD>::vals = 10011768SCurtis.Dunham@arm.com {"unimp_ldd", 0x012, 6, {H, H, H}};*/ 10111768SCurtis.Dunham@arm.com 10211768SCurtis.Dunham@arm.com//XXX This trap is apparently dropped from ua2005 10311768SCurtis.Dunham@arm.com/*template<> SparcFaultBase::FaultVals 10411768SCurtis.Dunham@arm.com SparcFault<UnimplementedSTD>::vals = 10511768SCurtis.Dunham@arm.com {"unimp_std", 0x013, 6, {H, H, H}};*/ 10611768SCurtis.Dunham@arm.com 10711768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 10811768SCurtis.Dunham@arm.com SparcFault<FpDisabled>::vals = 10911768SCurtis.Dunham@arm.com{"fp_disabled", 0x020, 800, {P, P, H}, FaultStat()}; 11011768SCurtis.Dunham@arm.com 11111768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 11211768SCurtis.Dunham@arm.com SparcFault<FpExceptionIEEE754>::vals = 11311768SCurtis.Dunham@arm.com{"fp_exception_ieee_754", 0x021, 1110, {P, P, H}, FaultStat()}; 11411768SCurtis.Dunham@arm.com 11510037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 11611768SCurtis.Dunham@arm.com SparcFault<FpExceptionOther>::vals = 11711768SCurtis.Dunham@arm.com{"fp_exception_other", 0x022, 1110, {P, P, H}, FaultStat()}; 11811768SCurtis.Dunham@arm.com 11911768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 12010037SARM gem5 Developers SparcFault<TagOverflow>::vals = 12111768SCurtis.Dunham@arm.com{"tag_overflow", 0x023, 1400, {P, P, H}, FaultStat()}; 12211768SCurtis.Dunham@arm.com 12311768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 12411768SCurtis.Dunham@arm.com SparcFault<CleanWindow>::vals = 12511768SCurtis.Dunham@arm.com{"clean_window", 0x024, 1010, {P, P, H}, FaultStat()}; 12611768SCurtis.Dunham@arm.com 12710037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 12811768SCurtis.Dunham@arm.com SparcFault<DivisionByZero>::vals = 12911768SCurtis.Dunham@arm.com{"division_by_zero", 0x028, 1500, {P, P, H}, FaultStat()}; 13011768SCurtis.Dunham@arm.com 13111768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 13211768SCurtis.Dunham@arm.com SparcFault<InternalProcessorError>::vals = 13311768SCurtis.Dunham@arm.com{"internal_processor_error", 0x029, 4, {H, H, H}, FaultStat()}; 13411768SCurtis.Dunham@arm.com 13511768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 13611768SCurtis.Dunham@arm.com SparcFault<InstructionInvalidTSBEntry>::vals = 13711768SCurtis.Dunham@arm.com{"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}, FaultStat()}; 13811768SCurtis.Dunham@arm.com 13911768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 14011768SCurtis.Dunham@arm.com SparcFault<DataInvalidTSBEntry>::vals = 14111768SCurtis.Dunham@arm.com{"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}, FaultStat()}; 14211768SCurtis.Dunham@arm.com 14311768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 14411768SCurtis.Dunham@arm.com SparcFault<DataAccessException>::vals = 14511768SCurtis.Dunham@arm.com{"data_access_exception", 0x030, 1201, {H, H, H}, FaultStat()}; 14611768SCurtis.Dunham@arm.com 14711768SCurtis.Dunham@arm.com//XXX This trap is apparently dropped from ua2005 14811768SCurtis.Dunham@arm.com/*template<> SparcFaultBase::FaultVals 14911768SCurtis.Dunham@arm.com SparcFault<DataAccessMMUMiss>::vals = 15011768SCurtis.Dunham@arm.com {"data_mmu", 0x031, 12, {H, H, H}};*/ 15111768SCurtis.Dunham@arm.com 15211768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 15311768SCurtis.Dunham@arm.com SparcFault<DataAccessError>::vals = 15411768SCurtis.Dunham@arm.com{"data_access_error", 0x032, 1210, {H, H, H}, FaultStat()}; 15511768SCurtis.Dunham@arm.com 15611768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 15711768SCurtis.Dunham@arm.com SparcFault<DataAccessProtection>::vals = 15811768SCurtis.Dunham@arm.com{"data_access_protection", 0x033, 1207, {H, H, H}, FaultStat()}; 15911768SCurtis.Dunham@arm.com 16011768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 16111768SCurtis.Dunham@arm.com SparcFault<MemAddressNotAligned>::vals = 16211768SCurtis.Dunham@arm.com{"mem_address_not_aligned", 0x034, 1020, {H, H, H}, FaultStat()}; 16311768SCurtis.Dunham@arm.com 16411768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 16511768SCurtis.Dunham@arm.com SparcFault<LDDFMemAddressNotAligned>::vals = 16611768SCurtis.Dunham@arm.com{"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}, FaultStat()}; 16711768SCurtis.Dunham@arm.com 16811768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 16911768SCurtis.Dunham@arm.com SparcFault<STDFMemAddressNotAligned>::vals = 17011768SCurtis.Dunham@arm.com{"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}, FaultStat()}; 17111768SCurtis.Dunham@arm.com 17211768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 17311768SCurtis.Dunham@arm.com SparcFault<PrivilegedAction>::vals = 17411768SCurtis.Dunham@arm.com{"privileged_action", 0x037, 1110, {H, H, SH}, FaultStat()}; 17511768SCurtis.Dunham@arm.com 17611768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 17711768SCurtis.Dunham@arm.com SparcFault<LDQFMemAddressNotAligned>::vals = 17811768SCurtis.Dunham@arm.com{"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}, FaultStat()}; 17911768SCurtis.Dunham@arm.com 18011768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 18111768SCurtis.Dunham@arm.com SparcFault<STQFMemAddressNotAligned>::vals = 18211768SCurtis.Dunham@arm.com{"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}, FaultStat()}; 18311768SCurtis.Dunham@arm.com 18411768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 18511768SCurtis.Dunham@arm.com SparcFault<InstructionRealTranslationMiss>::vals = 18611768SCurtis.Dunham@arm.com{"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}, FaultStat()}; 18711768SCurtis.Dunham@arm.com 18811768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 18911768SCurtis.Dunham@arm.com SparcFault<DataRealTranslationMiss>::vals = 19011768SCurtis.Dunham@arm.com{"data_real_translation_miss", 0x03F, 1203, {H, H, H}, FaultStat()}; 19111768SCurtis.Dunham@arm.com 19211768SCurtis.Dunham@arm.com//XXX This trap is apparently dropped from ua2005 19311768SCurtis.Dunham@arm.com/*template<> SparcFaultBase::FaultVals 19411768SCurtis.Dunham@arm.com SparcFault<AsyncDataError>::vals = 19511768SCurtis.Dunham@arm.com {"async_data", 0x040, 2, {H, H, H}};*/ 19611768SCurtis.Dunham@arm.com 19711768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 19811768SCurtis.Dunham@arm.com SparcFault<InterruptLevelN>::vals = 19911768SCurtis.Dunham@arm.com{"interrupt_level_n", 0x040, 0, {P, P, SH}, FaultStat()}; 20011768SCurtis.Dunham@arm.com 20111768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 20211768SCurtis.Dunham@arm.com SparcFault<HstickMatch>::vals = 20311768SCurtis.Dunham@arm.com{"hstick_match", 0x05E, 1601, {H, H, H}, FaultStat()}; 20411768SCurtis.Dunham@arm.com 20510037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 20610037SARM gem5 Developers SparcFault<TrapLevelZero>::vals = 20710037SARM gem5 Developers{"trap_level_zero", 0x05F, 202, {H, H, SH}, FaultStat()}; 2089384SAndreas.Sandberg@arm.com 20910461SAndreas.Sandberg@ARM.comtemplate<> SparcFaultBase::FaultVals 21010461SAndreas.Sandberg@ARM.com SparcFault<InterruptVector>::vals = 21111165SRekai.GonzalezAlberquilla@arm.com{"interrupt_vector", 0x060, 2630, {H, H, H}, FaultStat()}; 21212109SRekai.GonzalezAlberquilla@arm.com 21310461SAndreas.Sandberg@ARM.comtemplate<> SparcFaultBase::FaultVals 21410461SAndreas.Sandberg@ARM.com SparcFault<PAWatchpoint>::vals = 2159384SAndreas.Sandberg@arm.com{"PA_watchpoint", 0x061, 1209, {H, H, H}, FaultStat()}; 21611770SCurtis.Dunham@arm.com 21710037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 21810461SAndreas.Sandberg@ARM.com SparcFault<VAWatchpoint>::vals = 21910461SAndreas.Sandberg@ARM.com{"VA_watchpoint", 0x062, 1120, {P, P, SH}, FaultStat()}; 22010461SAndreas.Sandberg@ARM.com 22110461SAndreas.Sandberg@ARM.comtemplate<> SparcFaultBase::FaultVals 22210461SAndreas.Sandberg@ARM.com SparcFault<FastInstructionAccessMMUMiss>::vals = 22310461SAndreas.Sandberg@ARM.com{"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}, FaultStat()}; 22410609Sandreas.sandberg@arm.com 22510609Sandreas.sandberg@arm.comtemplate<> SparcFaultBase::FaultVals 22610609Sandreas.sandberg@arm.com SparcFault<FastDataAccessMMUMiss>::vals = 22710037SARM gem5 Developers{"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}, FaultStat()}; 22810037SARM gem5 Developers 22910037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 23010037SARM gem5 Developers SparcFault<FastDataAccessProtection>::vals = 23111771SCurtis.Dunham@arm.com{"fast_data_access_protection", 0x06C, 1207, {H, H, H}, FaultStat()}; 23210037SARM gem5 Developers 23310037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 23410037SARM gem5 Developers SparcFault<InstructionBreakpoint>::vals = 23510037SARM gem5 Developers{"instruction_break", 0x076, 610, {H, H, H}, FaultStat()}; 23610037SARM gem5 Developers 23710037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 23811771SCurtis.Dunham@arm.com SparcFault<CpuMondo>::vals = 23910037SARM gem5 Developers{"cpu_mondo", 0x07C, 1608, {P, P, SH}, FaultStat()}; 24010037SARM gem5 Developers 24110037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 24210037SARM gem5 Developers SparcFault<DevMondo>::vals = 24310037SARM gem5 Developers{"dev_mondo", 0x07D, 1611, {P, P, SH}, FaultStat()}; 24410037SARM gem5 Developers 24511768SCurtis.Dunham@arm.comtemplate<> SparcFaultBase::FaultVals 24611768SCurtis.Dunham@arm.com SparcFault<ResumableError>::vals = 24710037SARM gem5 Developers{"resume_error", 0x07E, 3330, {P, P, SH}, FaultStat()}; 24810037SARM gem5 Developers 24910037SARM gem5 Developerstemplate<> SparcFaultBase::FaultVals 25010037SARM gem5 Developers SparcFault<SpillNNormal>::vals = 2519384SAndreas.Sandberg@arm.com{"spill_n_normal", 0x080, 900, {P, P, H}, FaultStat()}; 2529384SAndreas.Sandberg@arm.com 2539384SAndreas.Sandberg@arm.comtemplate<> SparcFaultBase::FaultVals 2549384SAndreas.Sandberg@arm.com SparcFault<SpillNOther>::vals = 2559384SAndreas.Sandberg@arm.com{"spill_n_other", 0x0A0, 900, {P, P, H}, FaultStat()}; 2569384SAndreas.Sandberg@arm.com 2579384SAndreas.Sandberg@arm.comtemplate<> SparcFaultBase::FaultVals 2589384SAndreas.Sandberg@arm.com SparcFault<FillNNormal>::vals = 2599384SAndreas.Sandberg@arm.com{"fill_n_normal", 0x0C0, 900, {P, P, H}, FaultStat()}; 2607427Sgblack@eecs.umich.edu 2617427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 2627427Sgblack@eecs.umich.edu SparcFault<FillNOther>::vals = 2639385SAndreas.Sandberg@arm.com{"fill_n_other", 0x0E0, 900, {P, P, H}, FaultStat()}; 2649385SAndreas.Sandberg@arm.com 2657427Sgblack@eecs.umich.edutemplate<> SparcFaultBase::FaultVals 2667427Sgblack@eecs.umich.edu SparcFault<TrapInstruction>::vals = 26710037SARM gem5 Developers{"trap_instruction", 0x100, 1602, {P, P, H}, FaultStat()}; 26810037SARM gem5 Developers 26910037SARM gem5 Developers/** 27010037SARM gem5 Developers * This causes the thread context to enter RED state. This causes the side 27110037SARM gem5 Developers * effects which go with entering RED state because of a trap. 27210037SARM gem5 Developers */ 27310037SARM gem5 Developers 27410037SARM gem5 Developersvoid 27510037SARM gem5 DevelopersenterREDState(ThreadContext *tc) 27610037SARM gem5 Developers{ 27710037SARM gem5 Developers //@todo Disable the mmu? 27810037SARM gem5 Developers //@todo Disable watchpoints? 27910037SARM gem5 Developers HPSTATE hpstate= tc->readMiscRegNoEffect(MISCREG_HPSTATE); 28010037SARM gem5 Developers hpstate.red = 1; 2817427Sgblack@eecs.umich.edu hpstate.hpriv = 1; 2827427Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_HPSTATE, hpstate); 2837427Sgblack@eecs.umich.edu // PSTATE.priv is set to 1 here. The manual says it should be 0, but 2847427Sgblack@eecs.umich.edu // Legion sets it to 1. 2857427Sgblack@eecs.umich.edu PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 2867427Sgblack@eecs.umich.edu pstate.priv = 1; 28710037SARM gem5 Developers tc->setMiscReg(MISCREG_PSTATE, pstate); 28810037SARM gem5 Developers} 28910037SARM gem5 Developers 29010037SARM gem5 Developers/** 2917427Sgblack@eecs.umich.edu * This sets everything up for a RED state trap except for actually jumping to 2927427Sgblack@eecs.umich.edu * the handler. 2937427Sgblack@eecs.umich.edu */ 29410037SARM gem5 Developers 29510204SAli.Saidi@ARM.comvoid 29610204SAli.Saidi@ARM.comdoREDFault(ThreadContext *tc, TrapType tt) 29710037SARM gem5 Developers{ 2987427Sgblack@eecs.umich.edu MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 29910037SARM gem5 Developers MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 3007427Sgblack@eecs.umich.edu PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 30110037SARM gem5 Developers HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 3027427Sgblack@eecs.umich.edu MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 3037427Sgblack@eecs.umich.edu MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 30410037SARM gem5 Developers MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); 3057427Sgblack@eecs.umich.edu MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3); 3067427Sgblack@eecs.umich.edu MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 3077427Sgblack@eecs.umich.edu PCState pc = tc->pcState(); 3087427Sgblack@eecs.umich.edu 3097427Sgblack@eecs.umich.edu TL++; 3107427Sgblack@eecs.umich.edu 3117427Sgblack@eecs.umich.edu Addr pcMask = pstate.am ? mask(32) : mask(64); 3127427Sgblack@eecs.umich.edu 3137427Sgblack@eecs.umich.edu // set TSTATE.gl to gl 3147427Sgblack@eecs.umich.edu replaceBits(TSTATE, 42, 40, GL); 3157427Sgblack@eecs.umich.edu // set TSTATE.ccr to ccr 3167427Sgblack@eecs.umich.edu replaceBits(TSTATE, 39, 32, CCR); 3177427Sgblack@eecs.umich.edu // set TSTATE.asi to asi 3187427Sgblack@eecs.umich.edu replaceBits(TSTATE, 31, 24, ASI); 3197427Sgblack@eecs.umich.edu // set TSTATE.pstate to pstate 3207427Sgblack@eecs.umich.edu replaceBits(TSTATE, 20, 8, pstate); 3217427Sgblack@eecs.umich.edu // set TSTATE.cwp to cwp 3227427Sgblack@eecs.umich.edu replaceBits(TSTATE, 4, 0, CWP); 3237427Sgblack@eecs.umich.edu 3247427Sgblack@eecs.umich.edu // Write back TSTATE 3257427Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 3267427Sgblack@eecs.umich.edu 3277427Sgblack@eecs.umich.edu // set TPC to PC 3287436Sdam.sunwoo@arm.com tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask); 3297436Sdam.sunwoo@arm.com // set TNPC to NPC 33010037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); 33110037SARM gem5 Developers 3327436Sdam.sunwoo@arm.com // set HTSTATE.hpstate to hpstate 3337436Sdam.sunwoo@arm.com tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate); 3347436Sdam.sunwoo@arm.com 3357436Sdam.sunwoo@arm.com // TT = trap type; 3367436Sdam.sunwoo@arm.com tc->setMiscRegNoEffect(MISCREG_TT, tt); 3377436Sdam.sunwoo@arm.com 3387436Sdam.sunwoo@arm.com // Update GL 3397436Sdam.sunwoo@arm.com tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); 3407436Sdam.sunwoo@arm.com 3417436Sdam.sunwoo@arm.com bool priv = pstate.priv; // just save the priv bit 3427436Sdam.sunwoo@arm.com pstate = 0; 3437436Sdam.sunwoo@arm.com pstate.priv = priv; 34410037SARM gem5 Developers pstate.pef = 1; 3457436Sdam.sunwoo@arm.com tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate); 3467436Sdam.sunwoo@arm.com 3477436Sdam.sunwoo@arm.com hpstate.red = 1; 3487436Sdam.sunwoo@arm.com hpstate.hpriv = 1; 3497436Sdam.sunwoo@arm.com hpstate.ibe = 0; 3507436Sdam.sunwoo@arm.com hpstate.tlz = 0; 3517436Sdam.sunwoo@arm.com tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate); 3527436Sdam.sunwoo@arm.com 3537436Sdam.sunwoo@arm.com bool changedCWP = true; 3547436Sdam.sunwoo@arm.com if (tt == 0x24) 3557436Sdam.sunwoo@arm.com CWP++; 3567436Sdam.sunwoo@arm.com else if (0x80 <= tt && tt <= 0xbf) 3577436Sdam.sunwoo@arm.com CWP += (CANSAVE + 2); 3587436Sdam.sunwoo@arm.com else if (0xc0 <= tt && tt <= 0xff) 3597436Sdam.sunwoo@arm.com CWP--; 3607436Sdam.sunwoo@arm.com else 3617644Sali.saidi@arm.com changedCWP = false; 3628147SAli.Saidi@ARM.com 3639385SAndreas.Sandberg@arm.com if (changedCWP) { 3649385SAndreas.Sandberg@arm.com CWP = (CWP + NWindows) % NWindows; 3659385SAndreas.Sandberg@arm.com tc->setMiscReg(MISCREG_CWP, CWP); 3669385SAndreas.Sandberg@arm.com } 3679385SAndreas.Sandberg@arm.com} 3689385SAndreas.Sandberg@arm.com 3699385SAndreas.Sandberg@arm.com/** 3709385SAndreas.Sandberg@arm.com * This sets everything up for a normal trap except for actually jumping to 3719385SAndreas.Sandberg@arm.com * the handler. 3729385SAndreas.Sandberg@arm.com */ 3739385SAndreas.Sandberg@arm.com 3749385SAndreas.Sandberg@arm.comvoid 3759385SAndreas.Sandberg@arm.comdoNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) 3769385SAndreas.Sandberg@arm.com{ 37710037SARM gem5 Developers MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 37810037SARM gem5 Developers MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 37910037SARM gem5 Developers PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 38010037SARM gem5 Developers HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 38110037SARM gem5 Developers MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 38210037SARM gem5 Developers MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 38310037SARM gem5 Developers MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); 38410037SARM gem5 Developers MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); 38510037SARM gem5 Developers MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 38610037SARM gem5 Developers PCState pc = tc->pcState(); 38710037SARM gem5 Developers 38810037SARM gem5 Developers // Increment the trap level 38910037SARM gem5 Developers TL++; 39010037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TL, TL); 39110037SARM gem5 Developers 39210037SARM gem5 Developers Addr pcMask = pstate.am ? mask(32) : mask(64); 3938147SAli.Saidi@ARM.com 3947427Sgblack@eecs.umich.edu // Save off state 3957427Sgblack@eecs.umich.edu 3967427Sgblack@eecs.umich.edu // set TSTATE.gl to gl 39710037SARM gem5 Developers replaceBits(TSTATE, 42, 40, GL); 39810037SARM gem5 Developers // set TSTATE.ccr to ccr 39910037SARM gem5 Developers replaceBits(TSTATE, 39, 32, CCR); 40010037SARM gem5 Developers // set TSTATE.asi to asi 40110037SARM gem5 Developers replaceBits(TSTATE, 31, 24, ASI); 40210037SARM gem5 Developers // set TSTATE.pstate to pstate 40310037SARM gem5 Developers replaceBits(TSTATE, 20, 8, pstate); 40410037SARM gem5 Developers // set TSTATE.cwp to cwp 40510037SARM gem5 Developers replaceBits(TSTATE, 4, 0, CWP); 40610037SARM gem5 Developers 40710037SARM gem5 Developers // Write back TSTATE 40810037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 40910037SARM gem5 Developers 41010037SARM gem5 Developers // set TPC to PC 41110037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask); 41210037SARM gem5 Developers // set TNPC to NPC 41310037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); 41410037SARM gem5 Developers 41510037SARM gem5 Developers // set HTSTATE.hpstate to hpstate 41610037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate); 41710037SARM gem5 Developers 41810037SARM gem5 Developers // TT = trap type; 41910037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TT, tt); 42010037SARM gem5 Developers 42110037SARM gem5 Developers // Update the global register level 42210037SARM gem5 Developers if (!gotoHpriv) 42310037SARM gem5 Developers tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxPGL)); 42410037SARM gem5 Developers else 42510037SARM gem5 Developers tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL)); 42610037SARM gem5 Developers 42710037SARM gem5 Developers // pstate.mm is unchanged 42810037SARM gem5 Developers pstate.pef = 1; // PSTATE.pef = whether or not an fpu is present 42910037SARM gem5 Developers pstate.am = 0; 43010037SARM gem5 Developers pstate.ie = 0; 43110037SARM gem5 Developers // pstate.tle is unchanged 43210037SARM gem5 Developers // pstate.tct = 0 43311770SCurtis.Dunham@arm.com 43410037SARM gem5 Developers if (gotoHpriv) { 43511574SCurtis.Dunham@arm.com pstate.cle = 0; 43611770SCurtis.Dunham@arm.com // The manual says PSTATE.priv should be 0, but Legion leaves it alone 43711770SCurtis.Dunham@arm.com hpstate.red = 0; 43810037SARM gem5 Developers hpstate.hpriv = 1; 43911770SCurtis.Dunham@arm.com hpstate.ibe = 0; 44011770SCurtis.Dunham@arm.com // hpstate.tlz is unchanged 44110037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate); 44210037SARM gem5 Developers } else { // we are going to priv 44310037SARM gem5 Developers pstate.priv = 1; 44410037SARM gem5 Developers pstate.cle = pstate.tle; 44510037SARM gem5 Developers } 44610037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate); 44710037SARM gem5 Developers 44810461SAndreas.Sandberg@ARM.com 44910461SAndreas.Sandberg@ARM.com bool changedCWP = true; 45010461SAndreas.Sandberg@ARM.com if (tt == 0x24) 45110461SAndreas.Sandberg@ARM.com CWP++; 45210037SARM gem5 Developers else if (0x80 <= tt && tt <= 0xbf) 45310037SARM gem5 Developers CWP += (CANSAVE + 2); 45410037SARM gem5 Developers else if (0xc0 <= tt && tt <= 0xff) 45510037SARM gem5 Developers CWP--; 45610037SARM gem5 Developers else 45710037SARM gem5 Developers changedCWP = false; 45810461SAndreas.Sandberg@ARM.com 45910461SAndreas.Sandberg@ARM.com if (changedCWP) { 46010461SAndreas.Sandberg@ARM.com CWP = (CWP + NWindows) % NWindows; 46110461SAndreas.Sandberg@ARM.com tc->setMiscReg(MISCREG_CWP, CWP); 46210461SAndreas.Sandberg@ARM.com } 46310037SARM gem5 Developers} 46410037SARM gem5 Developers 46510037SARM gem5 Developersvoid 46610037SARM gem5 DevelopersgetREDVector(MiscReg TT, Addr &PC, Addr &NPC) 46710037SARM gem5 Developers{ 46811574SCurtis.Dunham@arm.com //XXX The following constant might belong in a header file. 46910037SARM gem5 Developers const Addr RSTVAddr = 0xFFF0000000ULL; 47010037SARM gem5 Developers PC = RSTVAddr | ((TT << 5) & 0xFF); 47110037SARM gem5 Developers NPC = PC + sizeof(MachInst); 47211574SCurtis.Dunham@arm.com} 47310037SARM gem5 Developers 47410037SARM gem5 Developersvoid 47510037SARM gem5 DevelopersgetHyperVector(ThreadContext * tc, Addr &PC, Addr &NPC, MiscReg TT) 47610037SARM gem5 Developers{ 47710037SARM gem5 Developers Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA); 47810037SARM gem5 Developers PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); 47910037SARM gem5 Developers NPC = PC + sizeof(MachInst); 48010037SARM gem5 Developers} 48110037SARM gem5 Developers 48210037SARM gem5 Developersvoid 4837405SAli.Saidi@ARM.comgetPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, MiscReg TT, MiscReg TL) 48410035Sandreas.hansson@arm.com{ 4857405SAli.Saidi@ARM.com Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA); 4867405SAli.Saidi@ARM.com PC = (TBA & ~mask(15)) | 4877614Sminkyu.jeong@arm.com (TL > 1 ? (1 << 14) : 0) | 48811771SCurtis.Dunham@arm.com ((TT << 5) & mask(14)); 48911771SCurtis.Dunham@arm.com NPC = PC + sizeof(MachInst); 49011771SCurtis.Dunham@arm.com} 49111771SCurtis.Dunham@arm.com 4927405SAli.Saidi@ARM.comvoid 4937405SAli.Saidi@ARM.comSparcFaultBase::invoke(ThreadContext * tc, const StaticInstPtr &inst) 4947405SAli.Saidi@ARM.com{ 4957405SAli.Saidi@ARM.com FaultBase::invoke(tc); 4967405SAli.Saidi@ARM.com if (!FullSystem) 4977405SAli.Saidi@ARM.com return; 49810037SARM gem5 Developers 49910037SARM gem5 Developers countStat()++; 50010037SARM gem5 Developers 5019050Schander.sudanthi@arm.com // We can refer to this to see what the trap level -was-, but something 5027405SAli.Saidi@ARM.com // in the middle could change it in the regfile out from under us. 50310037SARM gem5 Developers MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL); 50410037SARM gem5 Developers MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT); 5057720Sgblack@eecs.umich.edu PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 5067720Sgblack@eecs.umich.edu HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 5077405SAli.Saidi@ARM.com 5087405SAli.Saidi@ARM.com Addr PC, NPC; 5097757SAli.Saidi@ARM.com 51010037SARM gem5 Developers PrivilegeLevel current; 51110037SARM gem5 Developers if (hpstate.hpriv) 51210037SARM gem5 Developers current = Hyperprivileged; 51310037SARM gem5 Developers else if (pstate.priv) 51410037SARM gem5 Developers current = Privileged; 51510037SARM gem5 Developers else 51610037SARM gem5 Developers current = User; 51710037SARM gem5 Developers 51810037SARM gem5 Developers PrivilegeLevel level = getNextLevel(current); 51910037SARM gem5 Developers 52010037SARM gem5 Developers if (hpstate.red || (tl == MaxTL - 1)) { 52110037SARM gem5 Developers getREDVector(5, PC, NPC); 52210037SARM gem5 Developers doREDFault(tc, tt); 52310037SARM gem5 Developers // This changes the hpstate and pstate, so we need to make sure we 52410037SARM gem5 Developers // save the old version on the trap stack in doREDFault. 52510037SARM gem5 Developers enterREDState(tc); 52610037SARM gem5 Developers } else if (tl == MaxTL) { 52710037SARM gem5 Developers panic("Should go to error state here.. crap\n"); 52810037SARM gem5 Developers // Do error_state somehow? 52910037SARM gem5 Developers // Probably inject a WDR fault using the interrupt mechanism. 53010037SARM gem5 Developers // What should the PC and NPC be set to? 53110037SARM gem5 Developers } else if (tl > MaxPTL && level == Privileged) { 53210037SARM gem5 Developers // guest_watchdog fault 53310037SARM gem5 Developers doNormalFault(tc, trapType(), true); 53410037SARM gem5 Developers getHyperVector(tc, PC, NPC, 2); 53510037SARM gem5 Developers } else if (level == Hyperprivileged || 53610037SARM gem5 Developers (level == Privileged && trapType() >= 384)) { 53710037SARM gem5 Developers doNormalFault(tc, trapType(), true); 53810037SARM gem5 Developers getHyperVector(tc, PC, NPC, trapType()); 53910037SARM gem5 Developers } else { 54010037SARM gem5 Developers doNormalFault(tc, trapType(), false); 54110037SARM gem5 Developers getPrivVector(tc, PC, NPC, trapType(), tl + 1); 54210037SARM gem5 Developers } 54310037SARM gem5 Developers 54410037SARM gem5 Developers PCState pc; 54510037SARM gem5 Developers pc.pc(PC); 54610037SARM gem5 Developers pc.npc(NPC); 54710037SARM gem5 Developers pc.nnpc(NPC + sizeof(MachInst)); 54810037SARM gem5 Developers pc.upc(0); 54910037SARM gem5 Developers pc.nupc(1); 55010037SARM gem5 Developers tc->pcState(pc); 55110037SARM gem5 Developers} 55210037SARM gem5 Developers 55310037SARM gem5 Developersvoid 55410037SARM gem5 DevelopersPowerOnReset::invoke(ThreadContext *tc, const StaticInstPtr &inst) 55510037SARM gem5 Developers{ 5568284SAli.Saidi@ARM.com // For SPARC, when a system is first started, there is a power 55710037SARM gem5 Developers // on reset Trap which sets the processor into the following state. 55810037SARM gem5 Developers // Bits that aren't set aren't defined on startup. 55910037SARM gem5 Developers 56010037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TL, MaxTL); 5619050Schander.sudanthi@arm.com tc->setMiscRegNoEffect(MISCREG_TT, trapType()); 56210037SARM gem5 Developers tc->setMiscReg(MISCREG_GL, MaxGL); 56310037SARM gem5 Developers 56410037SARM gem5 Developers PSTATE pstate = 0; 56510037SARM gem5 Developers pstate.pef = 1; 56610037SARM gem5 Developers pstate.priv = 1; 56710037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate); 56810037SARM gem5 Developers 56910037SARM gem5 Developers // Turn on red and hpriv, set everything else to 0 57010037SARM gem5 Developers HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 57110037SARM gem5 Developers hpstate.red = 1; 57210037SARM gem5 Developers hpstate.hpriv = 1; 57310037SARM gem5 Developers hpstate.ibe = 0; 57410037SARM gem5 Developers hpstate.tlz = 0; 57510037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate); 57610037SARM gem5 Developers 57710037SARM gem5 Developers // The tick register is unreadable by nonprivileged software 57810037SARM gem5 Developers tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63); 57910037SARM gem5 Developers 5809050Schander.sudanthi@arm.com // Enter RED state. We do this last so that the actual state preserved in 5818284SAli.Saidi@ARM.com // the trap stack is the state from before this fault. 58210037SARM gem5 Developers enterREDState(tc); 58310037SARM gem5 Developers 58410037SARM gem5 Developers Addr PC, NPC; 58510037SARM gem5 Developers getREDVector(trapType(), PC, NPC); 58610037SARM gem5 Developers 58710037SARM gem5 Developers PCState pc; 58810037SARM gem5 Developers pc.pc(PC); 5897405SAli.Saidi@ARM.com pc.npc(NPC); 5907731SAli.Saidi@ARM.com pc.nnpc(NPC + sizeof(MachInst)); 5918468Swade.walker@arm.com pc.upc(0); 5928468Swade.walker@arm.com pc.nupc(1); 5938468Swade.walker@arm.com tc->pcState(pc); 5947405SAli.Saidi@ARM.com 5957731SAli.Saidi@ARM.com // These registers are specified as "undefined" after a POR, and they 5967405SAli.Saidi@ARM.com // should have reasonable values after the miscregfile is reset 5977405SAli.Saidi@ARM.com /* 59811809Sbaz21@cam.ac.uk // Clear all the soft interrupt bits 59911809Sbaz21@cam.ac.uk softint = 0; 6009130Satgutier@umich.edu // disable timer compare interrupts, reset tick_cmpr 6019130Satgutier@umich.edu tc->setMiscRegNoEffect(MISCREG_ 6029130Satgutier@umich.edu tick_cmprFields.int_dis = 1; 6039130Satgutier@umich.edu tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 6049814Sandreas.hansson@arm.com stickFields.npt = 1; // The TICK register is unreadable by by !priv 6059130Satgutier@umich.edu stick_cmprFields.int_dis = 1; // disable timer compare interrupts 6069130Satgutier@umich.edu stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 6079130Satgutier@umich.edu 6089130Satgutier@umich.edu tt[tl] = _trapType; 6099130Satgutier@umich.edu 6109130Satgutier@umich.edu hintp = 0; // no interrupts pending 6119130Satgutier@umich.edu hstick_cmprFields.int_dis = 1; // disable timer compare interrupts 6129130Satgutier@umich.edu hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 6139130Satgutier@umich.edu */ 6149130Satgutier@umich.edu} 6159130Satgutier@umich.edu 6169130Satgutier@umich.eduvoid 6179130Satgutier@umich.eduFastInstructionAccessMMUMiss::invoke(ThreadContext *tc, 6189130Satgutier@umich.edu const StaticInstPtr &inst) 6199130Satgutier@umich.edu{ 6209130Satgutier@umich.edu if (FullSystem) { 6219130Satgutier@umich.edu SparcFaultBase::invoke(tc, inst); 6229130Satgutier@umich.edu return; 6239130Satgutier@umich.edu } 6249130Satgutier@umich.edu 6259130Satgutier@umich.edu Process *p = tc->getProcessPtr(); 6269130Satgutier@umich.edu TlbEntry entry; 6277583SAli.Saidi@arm.com bool success = p->pTable->lookup(vaddr, entry); 6287583SAli.Saidi@arm.com if (!success) { 6297583SAli.Saidi@arm.com panic("Tried to execute unmapped address %#x.\n", vaddr); 63010461SAndreas.Sandberg@ARM.com } else { 63110461SAndreas.Sandberg@ARM.com Addr alignedvaddr = p->pTable->pageAlign(vaddr); 63210461SAndreas.Sandberg@ARM.com 63310461SAndreas.Sandberg@ARM.com // Grab fields used during instruction translation to figure out 63410461SAndreas.Sandberg@ARM.com // which context to use. 63510461SAndreas.Sandberg@ARM.com uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); 63610461SAndreas.Sandberg@ARM.com 6378302SAli.Saidi@ARM.com // Inside a VM, a real address is the address that guest OS would 6388302SAli.Saidi@ARM.com // interpret to be a physical address. To map to the physical address, 6397783SGiacomo.Gabrielli@arm.com // it still needs to undergo a translation. The instruction 6407783SGiacomo.Gabrielli@arm.com // translation code in the SPARC ITLB code assumes that the context is 6417783SGiacomo.Gabrielli@arm.com // zero (kernel-level) if real addressing is being used. 6427783SGiacomo.Gabrielli@arm.com bool is_real_address = !bits(tlbdata, 4); 64310037SARM gem5 Developers 64410037SARM gem5 Developers // The SPARC ITLB code assumes that traps are executed in context 64510037SARM gem5 Developers // zero so we carry that assumption through here. 64610037SARM gem5 Developers bool trapped = bits(tlbdata, 18, 16) > 0; 64710037SARM gem5 Developers 64810037SARM gem5 Developers // The primary context acts as a PASID. It allows the MMU to 64910037SARM gem5 Developers // distinguish between virtual addresses that would alias to the 65010037SARM gem5 Developers // same physical address (if two or more processes shared the same 65110037SARM gem5 Developers // virtual address mapping). 65210037SARM gem5 Developers int primary_context = bits(tlbdata, 47, 32); 65310037SARM gem5 Developers 65410037SARM gem5 Developers // The partition id distinguishes between virtualized environments. 65510037SARM gem5 Developers int const partition_id = 0; 65610037SARM gem5 Developers 65710037SARM gem5 Developers // Given the assumptions in the translateInst code in the SPARC ITLB, 65810037SARM gem5 Developers // the logic works out to the following for the context. 65910037SARM gem5 Developers int context_id = (is_real_address || trapped) ? 0 : primary_context; 66010037SARM gem5 Developers 66110037SARM gem5 Developers // Insert the TLB entry. 66210037SARM gem5 Developers // The entry specifying whether the address is "real" is set to 66310037SARM gem5 Developers // false for syscall emulation mode regardless of whether the 66410037SARM gem5 Developers // address is real in preceding code. Not sure sure that this is 66510037SARM gem5 Developers // correct, but also not sure if it matters at all. 66610037SARM gem5 Developers tc->getITBPtr()->insert(alignedvaddr, partition_id, context_id, 66710037SARM gem5 Developers false, entry.pte); 66810037SARM gem5 Developers } 66910037SARM gem5 Developers} 67010037SARM gem5 Developers 67110037SARM gem5 Developersvoid 67210037SARM gem5 DevelopersFastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst) 67310037SARM gem5 Developers{ 67410037SARM gem5 Developers if (FullSystem) { 67510037SARM gem5 Developers SparcFaultBase::invoke(tc, inst); 67610037SARM gem5 Developers return; 67710037SARM gem5 Developers } 67810037SARM gem5 Developers 67910037SARM gem5 Developers Process *p = tc->getProcessPtr(); 68010037SARM gem5 Developers TlbEntry entry; 68110338SCurtis.Dunham@arm.com bool success = p->pTable->lookup(vaddr, entry); 68210338SCurtis.Dunham@arm.com if (!success) { 68310338SCurtis.Dunham@arm.com if (p->fixupStackFault(vaddr)) 68410037SARM gem5 Developers success = p->pTable->lookup(vaddr, entry); 68510037SARM gem5 Developers } 68610037SARM gem5 Developers if (!success) { 68710037SARM gem5 Developers panic("Tried to access unmapped address %#x.\n", vaddr); 68810037SARM gem5 Developers } else { 68910037SARM gem5 Developers Addr alignedvaddr = p->pTable->pageAlign(vaddr); 69010037SARM gem5 Developers 69110037SARM gem5 Developers // Grab fields used during data translation to figure out 69210037SARM gem5 Developers // which context to use. 69310037SARM gem5 Developers uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); 69410037SARM gem5 Developers 69510037SARM gem5 Developers // The primary context acts as a PASID. It allows the MMU to 69610037SARM gem5 Developers // distinguish between virtual addresses that would alias to the 69710037SARM gem5 Developers // same physical address (if two or more processes shared the same 69810037SARM gem5 Developers // virtual address mapping). There's a secondary context used in the 69910037SARM gem5 Developers // DTLB translation code, but it should __probably__ be zero for 70010037SARM gem5 Developers // syscall emulation code. (The secondary context is used by Solaris 70110037SARM gem5 Developers // to allow kernel privilege code to access user space code: 70210037SARM gem5 Developers // [ISBN 0-13-022496-0]:PG199.) 70310037SARM gem5 Developers int primary_context = bits(tlbdata, 47, 32); 70410037SARM gem5 Developers 70510037SARM gem5 Developers // "Hyper-Privileged Mode" is in use. There are three main modes of 70610037SARM gem5 Developers // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and 70710037SARM gem5 Developers // User Mode. 70810037SARM gem5 Developers int hpriv = bits(tlbdata, 0); 70910037SARM gem5 Developers 71010037SARM gem5 Developers // Reset, Error and Debug state is in use. Something horrible has 71110037SARM gem5 Developers // happened or the system is operating in Reset Mode. 7128549Sdaniel.johnson@arm.com int red = bits(tlbdata, 1); 7138868SMatt.Horsnell@arm.com 7148868SMatt.Horsnell@arm.com // Inside a VM, a real address is the address that guest OS would 7158868SMatt.Horsnell@arm.com // interpret to be a physical address. To map to the physical address, 7168868SMatt.Horsnell@arm.com // it still needs to undergo a translation. The instruction 7178868SMatt.Horsnell@arm.com // translation code in the SPARC ITLB code assumes that the context is 7188868SMatt.Horsnell@arm.com // zero (kernel-level) if real addressing is being used. 7198868SMatt.Horsnell@arm.com int is_real_address = !bits(tlbdata, 5); 7208868SMatt.Horsnell@arm.com 7218868SMatt.Horsnell@arm.com // Grab the address space identifier register from the thread context. 72210461SAndreas.Sandberg@ARM.com // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for 7238868SMatt.Horsnell@arm.com // MISCREG_ASI causes me to think that the ASI register implementation 72410461SAndreas.Sandberg@ARM.com // might be bugged. The NoEffect variant changes the ASI register 72510037SARM gem5 Developers // value in the architectural state while the normal variant changes 7268868SMatt.Horsnell@arm.com // the context field in the thread context's currently decoded request 72710037SARM gem5 Developers // but does not directly affect the ASI register value in the 72811150Smitch.hayenga@arm.com // architectural state. The ASI values and the context field in the 72910037SARM gem5 Developers // request packet seem to have completely different uses. 73010037SARM gem5 Developers MiscReg reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI); 73110037SARM gem5 Developers ASI asi = static_cast<ASI>(reg_asi); 73210037SARM gem5 Developers 73311150Smitch.hayenga@arm.com // The SPARC DTLB code assumes that traps are executed in context 73410037SARM gem5 Developers // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also 73510037SARM gem5 Developers // an assumption that the nucleus address space is being used, but 73610037SARM gem5 Developers // the context is the relevant issue since we need to pass it to TLB. 73710037SARM gem5 Developers bool trapped = bits(tlbdata, 18, 16) > 0; 73810037SARM gem5 Developers 73910037SARM gem5 Developers // Given the assumptions in the translateData code in the SPARC DTLB, 74010037SARM gem5 Developers // the logic works out to the following for the context. 74110037SARM gem5 Developers int context_id = ((!hpriv && !red && is_real_address) || 74210037SARM gem5 Developers asiIsReal(asi) || 74310037SARM gem5 Developers (trapped && asi == ASI_IMPLICIT)) 74410037SARM gem5 Developers ? 0 : primary_context; 74510037SARM gem5 Developers 74610037SARM gem5 Developers // The partition id distinguishes between virtualized environments. 74710037SARM gem5 Developers int const partition_id = 0; 74810037SARM gem5 Developers 74910037SARM gem5 Developers // Insert the TLB entry. 75010037SARM gem5 Developers // The entry specifying whether the address is "real" is set to 75110037SARM gem5 Developers // false for syscall emulation mode regardless of whether the 75210037SARM gem5 Developers // address is real in preceding code. Not sure sure that this is 75310037SARM gem5 Developers // correct, but also not sure if it matters at all. 75410037SARM gem5 Developers tc->getDTBPtr()->insert(alignedvaddr, partition_id, context_id, 75510037SARM gem5 Developers false, entry.pte); 75610037SARM gem5 Developers } 75710037SARM gem5 Developers} 75810037SARM gem5 Developers 75910037SARM gem5 Developersvoid 76010037SARM gem5 DevelopersSpillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst) 76110037SARM gem5 Developers{ 76210037SARM gem5 Developers if (FullSystem) { 76311769SCurtis.Dunham@arm.com SparcFaultBase::invoke(tc, inst); 76411769SCurtis.Dunham@arm.com return; 76510037SARM gem5 Developers } 76611770SCurtis.Dunham@arm.com 76711770SCurtis.Dunham@arm.com doNormalFault(tc, trapType(), false); 76810037SARM gem5 Developers 76911770SCurtis.Dunham@arm.com Process *p = tc->getProcessPtr(); 77011769SCurtis.Dunham@arm.com 77110844Sandreas.sandberg@arm.com SparcProcess *sp = dynamic_cast<SparcProcess *>(p); 77211772SCurtis.Dunham@arm.com assert(sp); 77311772SCurtis.Dunham@arm.com 77411772SCurtis.Dunham@arm.com // Then adjust the PC and NPC 77511772SCurtis.Dunham@arm.com tc->pcState(sp->readSpillStart()); 77611774SCurtis.Dunham@arm.com} 77711774SCurtis.Dunham@arm.com 77811774SCurtis.Dunham@arm.comvoid 77911774SCurtis.Dunham@arm.comFillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst) 78011774SCurtis.Dunham@arm.com{ 78111774SCurtis.Dunham@arm.com if (FullSystem) { 78211774SCurtis.Dunham@arm.com SparcFaultBase::invoke(tc, inst); 78311773SCurtis.Dunham@arm.com return; 78411773SCurtis.Dunham@arm.com } 78511773SCurtis.Dunham@arm.com 78611773SCurtis.Dunham@arm.com doNormalFault(tc, trapType(), false); 78711773SCurtis.Dunham@arm.com 78811773SCurtis.Dunham@arm.com Process *p = tc->getProcessPtr(); 78911773SCurtis.Dunham@arm.com 79011772SCurtis.Dunham@arm.com SparcProcess *sp = dynamic_cast<SparcProcess *>(p); 79110037SARM gem5 Developers assert(sp); 79210844Sandreas.sandberg@arm.com 79310844Sandreas.sandberg@arm.com // Then adjust the PC and NPC 79410844Sandreas.sandberg@arm.com tc->pcState(sp->readFillStart()); 79510844Sandreas.sandberg@arm.com} 79610844Sandreas.sandberg@arm.com 79710844Sandreas.sandberg@arm.comvoid 79810188Sgeoffrey.blake@arm.comTrapInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst) 79910037SARM gem5 Developers{ 80010037SARM gem5 Developers if (FullSystem) { 8017405SAli.Saidi@ARM.com SparcFaultBase::invoke(tc, inst); 8027405SAli.Saidi@ARM.com return; 8037405SAli.Saidi@ARM.com } 8047405SAli.Saidi@ARM.com 8057405SAli.Saidi@ARM.com // In SE, this mechanism is how the process requests a service from 8067405SAli.Saidi@ARM.com // the operating system. We'll get the process object from the thread 8077405SAli.Saidi@ARM.com // context and let it service the request. 8087405SAli.Saidi@ARM.com 8097614Sminkyu.jeong@arm.com Process *p = tc->getProcessPtr(); 81011771SCurtis.Dunham@arm.com 81111771SCurtis.Dunham@arm.com SparcProcess *sp = dynamic_cast<SparcProcess *>(p); 81211771SCurtis.Dunham@arm.com assert(sp); 81311771SCurtis.Dunham@arm.com 81411771SCurtis.Dunham@arm.com sp->handleTrap(_n, tc); 81510037SARM gem5 Developers 81611771SCurtis.Dunham@arm.com // We need to explicitly advance the pc, since that's not done for us 81710037SARM gem5 Developers // on a faulting instruction 81811771SCurtis.Dunham@arm.com PCState pc = tc->pcState(); 81910037SARM gem5 Developers pc.advance(); 82011771SCurtis.Dunham@arm.com tc->pcState(pc); 82110037SARM gem5 Developers} 8227405SAli.Saidi@ARM.com 8237405SAli.Saidi@ARM.com} // namespace SparcISA 8247405SAli.Saidi@ARM.com 8257405SAli.Saidi@ARM.com