faults.cc revision 3415
12221SN/A/*
22221SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32221SN/A * All rights reserved.
42221SN/A *
52221SN/A * Redistribution and use in source and binary forms, with or without
62221SN/A * modification, are permitted provided that the following conditions are
72221SN/A * met: redistributions of source code must retain the above copyright
82221SN/A * notice, this list of conditions and the following disclaimer;
92221SN/A * redistributions in binary form must reproduce the above copyright
102221SN/A * notice, this list of conditions and the following disclaimer in the
112221SN/A * documentation and/or other materials provided with the distribution;
122221SN/A * neither the name of the copyright holders nor the names of its
132221SN/A * contributors may be used to endorse or promote products derived from
142221SN/A * this software without specific prior written permission.
152221SN/A *
162221SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172221SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182221SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192221SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202221SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212221SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222221SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232221SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242221SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252221SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262221SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Gabe Black
292665Ssaidi@eecs.umich.edu *          Kevin Lim
302221SN/A */
312221SN/A
323415Sgblack@eecs.umich.edu#include <algorithm>
333415Sgblack@eecs.umich.edu
342223SN/A#include "arch/sparc/faults.hh"
353415Sgblack@eecs.umich.edu#include "arch/sparc/isa_traits.hh"
363415Sgblack@eecs.umich.edu#include "arch/sparc/process.hh"
373415Sgblack@eecs.umich.edu#include "base/bitfield.hh"
383415Sgblack@eecs.umich.edu#include "base/trace.hh"
393415Sgblack@eecs.umich.edu#include "cpu/base.hh"
402680Sktlim@umich.edu#include "cpu/thread_context.hh"
412800Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
423415Sgblack@eecs.umich.edu#include "mem/page_table.hh"
432800Ssaidi@eecs.umich.edu#include "sim/process.hh"
442800Ssaidi@eecs.umich.edu#endif
452221SN/A
463415Sgblack@eecs.umich.eduusing namespace std;
473415Sgblack@eecs.umich.edu
482223SN/Anamespace SparcISA
492221SN/A{
502221SN/A
512223SN/AFaultName     InternalProcessorError::_name = "intprocerr";
522223SN/ATrapType      InternalProcessorError::_trapType = 0x029;
532223SN/AFaultPriority InternalProcessorError::_priority = 4;
542223SN/AFaultStat     InternalProcessorError::_count;
552221SN/A
562223SN/AFaultName     MemAddressNotAligned::_name = "unalign";
572223SN/ATrapType      MemAddressNotAligned::_trapType = 0x034;
582223SN/AFaultPriority MemAddressNotAligned::_priority = 10;
592223SN/AFaultStat     MemAddressNotAligned::_count;
602221SN/A
612223SN/AFaultName     PowerOnReset::_name = "pow_reset";
622223SN/ATrapType      PowerOnReset::_trapType = 0x001;
632223SN/AFaultPriority PowerOnReset::_priority = 0;
642223SN/AFaultStat     PowerOnReset::_count;
652221SN/A
662223SN/AFaultName     WatchDogReset::_name = "watch_dog_reset";
672223SN/ATrapType      WatchDogReset::_trapType = 0x002;
682223SN/AFaultPriority WatchDogReset::_priority = 1;
692223SN/AFaultStat     WatchDogReset::_count;
702221SN/A
712223SN/AFaultName     ExternallyInitiatedReset::_name = "extern_reset";
722223SN/ATrapType      ExternallyInitiatedReset::_trapType = 0x003;
732223SN/AFaultPriority ExternallyInitiatedReset::_priority = 1;
742223SN/AFaultStat     ExternallyInitiatedReset::_count;
752221SN/A
762223SN/AFaultName     SoftwareInitiatedReset::_name = "software_reset";
772223SN/ATrapType      SoftwareInitiatedReset::_trapType = 0x004;
782223SN/AFaultPriority SoftwareInitiatedReset::_priority = 1;
792223SN/AFaultStat     SoftwareInitiatedReset::_count;
802221SN/A
812223SN/AFaultName     REDStateException::_name = "red_counte";
822223SN/ATrapType      REDStateException::_trapType = 0x005;
832223SN/AFaultPriority REDStateException::_priority = 1;
842223SN/AFaultStat     REDStateException::_count;
852221SN/A
862223SN/AFaultName     InstructionAccessException::_name = "inst_access";
872223SN/ATrapType      InstructionAccessException::_trapType = 0x008;
882223SN/AFaultPriority InstructionAccessException::_priority = 5;
892223SN/AFaultStat     InstructionAccessException::_count;
902221SN/A
912223SN/AFaultName     InstructionAccessMMUMiss::_name = "inst_mmu";
922223SN/ATrapType      InstructionAccessMMUMiss::_trapType = 0x009;
932223SN/AFaultPriority InstructionAccessMMUMiss::_priority = 2;
942223SN/AFaultStat     InstructionAccessMMUMiss::_count;
952221SN/A
962223SN/AFaultName     InstructionAccessError::_name = "inst_error";
972223SN/ATrapType      InstructionAccessError::_trapType = 0x00A;
982223SN/AFaultPriority InstructionAccessError::_priority = 3;
992223SN/AFaultStat     InstructionAccessError::_count;
1002221SN/A
1012223SN/AFaultName     IllegalInstruction::_name = "illegal_inst";
1022223SN/ATrapType      IllegalInstruction::_trapType = 0x010;
1032223SN/AFaultPriority IllegalInstruction::_priority = 7;
1042223SN/AFaultStat     IllegalInstruction::_count;
1052221SN/A
1062469SN/AFaultName     PrivilegedOpcode::_name = "priv_opcode";
1072469SN/ATrapType      PrivilegedOpcode::_trapType = 0x011;
1082469SN/AFaultPriority PrivilegedOpcode::_priority = 6;
1092469SN/AFaultStat     PrivilegedOpcode::_count;
1102221SN/A
1112223SN/AFaultName     UnimplementedLDD::_name = "unimp_ldd";
1122223SN/ATrapType      UnimplementedLDD::_trapType = 0x012;
1132223SN/AFaultPriority UnimplementedLDD::_priority = 6;
1142223SN/AFaultStat     UnimplementedLDD::_count;
1152221SN/A
1162223SN/AFaultName     UnimplementedSTD::_name = "unimp_std";
1172223SN/ATrapType      UnimplementedSTD::_trapType = 0x013;
1182223SN/AFaultPriority UnimplementedSTD::_priority = 6;
1192223SN/AFaultStat     UnimplementedSTD::_count;
1202221SN/A
1212223SN/AFaultName     FpDisabled::_name = "fp_disabled";
1222223SN/ATrapType      FpDisabled::_trapType = 0x020;
1232223SN/AFaultPriority FpDisabled::_priority = 8;
1242223SN/AFaultStat     FpDisabled::_count;
1252221SN/A
1262223SN/AFaultName     FpExceptionIEEE754::_name = "fp_754";
1272223SN/ATrapType      FpExceptionIEEE754::_trapType = 0x021;
1282223SN/AFaultPriority FpExceptionIEEE754::_priority = 11;
1292223SN/AFaultStat     FpExceptionIEEE754::_count;
1302223SN/A
1312223SN/AFaultName     FpExceptionOther::_name = "fp_other";
1322223SN/ATrapType      FpExceptionOther::_trapType = 0x022;
1332223SN/AFaultPriority FpExceptionOther::_priority = 11;
1342223SN/AFaultStat     FpExceptionOther::_count;
1352223SN/A
1362223SN/AFaultName     TagOverflow::_name = "tag_overflow";
1372223SN/ATrapType      TagOverflow::_trapType = 0x023;
1382223SN/AFaultPriority TagOverflow::_priority = 14;
1392223SN/AFaultStat     TagOverflow::_count;
1402223SN/A
1412223SN/AFaultName     DivisionByZero::_name = "div_by_zero";
1422223SN/ATrapType      DivisionByZero::_trapType = 0x028;
1432223SN/AFaultPriority DivisionByZero::_priority = 15;
1442223SN/AFaultStat     DivisionByZero::_count;
1452223SN/A
1462223SN/AFaultName     DataAccessException::_name = "data_access";
1472223SN/ATrapType      DataAccessException::_trapType = 0x030;
1482223SN/AFaultPriority DataAccessException::_priority = 12;
1492223SN/AFaultStat     DataAccessException::_count;
1502223SN/A
1512223SN/AFaultName     DataAccessMMUMiss::_name = "data_mmu";
1522223SN/ATrapType      DataAccessMMUMiss::_trapType = 0x031;
1532223SN/AFaultPriority DataAccessMMUMiss::_priority = 12;
1542223SN/AFaultStat     DataAccessMMUMiss::_count;
1552223SN/A
1562223SN/AFaultName     DataAccessError::_name = "data_error";
1572223SN/ATrapType      DataAccessError::_trapType = 0x032;
1582223SN/AFaultPriority DataAccessError::_priority = 12;
1592223SN/AFaultStat     DataAccessError::_count;
1602223SN/A
1612223SN/AFaultName     DataAccessProtection::_name = "data_protection";
1622223SN/ATrapType      DataAccessProtection::_trapType = 0x033;
1632223SN/AFaultPriority DataAccessProtection::_priority = 12;
1642223SN/AFaultStat     DataAccessProtection::_count;
1652223SN/A
1662223SN/AFaultName     LDDFMemAddressNotAligned::_name = "unalign_lddf";
1672223SN/ATrapType      LDDFMemAddressNotAligned::_trapType = 0x035;
1682223SN/AFaultPriority LDDFMemAddressNotAligned::_priority = 10;
1692223SN/AFaultStat     LDDFMemAddressNotAligned::_count;
1702223SN/A
1712223SN/AFaultName     STDFMemAddressNotAligned::_name = "unalign_stdf";
1722223SN/ATrapType      STDFMemAddressNotAligned::_trapType = 0x036;
1732223SN/AFaultPriority STDFMemAddressNotAligned::_priority = 10;
1742223SN/AFaultStat     STDFMemAddressNotAligned::_count;
1752223SN/A
1762469SN/AFaultName     PrivilegedAction::_name = "priv_action";
1772469SN/ATrapType      PrivilegedAction::_trapType = 0x037;
1782469SN/AFaultPriority PrivilegedAction::_priority = 11;
1792469SN/AFaultStat     PrivilegedAction::_count;
1802223SN/A
1812223SN/AFaultName     LDQFMemAddressNotAligned::_name = "unalign_ldqf";
1822223SN/ATrapType      LDQFMemAddressNotAligned::_trapType = 0x038;
1832223SN/AFaultPriority LDQFMemAddressNotAligned::_priority = 10;
1842223SN/AFaultStat     LDQFMemAddressNotAligned::_count;
1852223SN/A
1862223SN/AFaultName     STQFMemAddressNotAligned::_name = "unalign_stqf";
1872223SN/ATrapType      STQFMemAddressNotAligned::_trapType = 0x039;
1882223SN/AFaultPriority STQFMemAddressNotAligned::_priority = 10;
1892223SN/AFaultStat     STQFMemAddressNotAligned::_count;
1902223SN/A
1912223SN/AFaultName     AsyncDataError::_name = "async_data";
1922223SN/ATrapType      AsyncDataError::_trapType = 0x040;
1932223SN/AFaultPriority AsyncDataError::_priority = 2;
1942223SN/AFaultStat     AsyncDataError::_count;
1952223SN/A
1962223SN/AFaultName     CleanWindow::_name = "clean_win";
1972527SN/ATrapType      CleanWindow::_trapType = 0x024;
1982223SN/AFaultPriority CleanWindow::_priority = 10;
1992223SN/AFaultStat     CleanWindow::_count;
2002223SN/A
2012527SN/A//The enumerated faults
2022527SN/A
2032223SN/AFaultName     InterruptLevelN::_name = "interrupt_n";
2042223SN/ATrapType      InterruptLevelN::_baseTrapType = 0x041;
2052223SN/AFaultStat     InterruptLevelN::_count;
2062223SN/A
2072223SN/AFaultName     SpillNNormal::_name = "spill_n_normal";
2082223SN/ATrapType      SpillNNormal::_baseTrapType = 0x080;
2092223SN/AFaultPriority SpillNNormal::_priority = 9;
2102223SN/AFaultStat     SpillNNormal::_count;
2112223SN/A
2122223SN/AFaultName     SpillNOther::_name = "spill_n_other";
2132223SN/ATrapType      SpillNOther::_baseTrapType = 0x0A0;
2142223SN/AFaultPriority SpillNOther::_priority = 9;
2152223SN/AFaultStat     SpillNOther::_count;
2162223SN/A
2172223SN/AFaultName     FillNNormal::_name = "fill_n_normal";
2182223SN/ATrapType      FillNNormal::_baseTrapType = 0x0C0;
2192223SN/AFaultPriority FillNNormal::_priority = 9;
2202223SN/AFaultStat     FillNNormal::_count;
2212223SN/A
2222223SN/AFaultName     FillNOther::_name = "fill_n_other";
2232223SN/ATrapType      FillNOther::_baseTrapType = 0x0E0;
2242223SN/AFaultPriority FillNOther::_priority = 9;
2252223SN/AFaultStat     FillNOther::_count;
2262223SN/A
2272223SN/AFaultName     TrapInstruction::_name = "trap_inst_n";
2282223SN/ATrapType      TrapInstruction::_baseTrapType = 0x100;
2292223SN/AFaultPriority TrapInstruction::_priority = 16;
2302223SN/AFaultStat     TrapInstruction::_count;
2312223SN/A
2322800Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
2332800Ssaidi@eecs.umich.eduFaultName PageTableFault::_name = "page_table_fault";
2342800Ssaidi@eecs.umich.eduTrapType PageTableFault::_trapType = 0x0000;
2352800Ssaidi@eecs.umich.eduFaultPriority PageTableFault::_priority = 0;
2362800Ssaidi@eecs.umich.eduFaultStat PageTableFault::_count;
2372800Ssaidi@eecs.umich.edu#endif
2382800Ssaidi@eecs.umich.edu
2393415Sgblack@eecs.umich.edu/**
2403415Sgblack@eecs.umich.edu * This sets everything up for a normal trap except for actually jumping to
2413415Sgblack@eecs.umich.edu * the handler. It will need to be expanded to include the state machine in
2423415Sgblack@eecs.umich.edu * the manual. Right now it assumes that traps will always be to the
2433415Sgblack@eecs.umich.edu * privileged level.
2443415Sgblack@eecs.umich.edu */
2453415Sgblack@eecs.umich.edu
2463415Sgblack@eecs.umich.eduvoid doNormalFault(ThreadContext *tc, TrapType tt)
2473415Sgblack@eecs.umich.edu{
2483415Sgblack@eecs.umich.edu    uint64_t TL = tc->readMiscReg(MISCREG_TL);
2493415Sgblack@eecs.umich.edu    uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE);
2503415Sgblack@eecs.umich.edu    uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE);
2513415Sgblack@eecs.umich.edu    uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
2523415Sgblack@eecs.umich.edu    uint64_t CCR = tc->readMiscReg(MISCREG_CCR);
2533415Sgblack@eecs.umich.edu    uint64_t ASI = tc->readMiscReg(MISCREG_ASI);
2543415Sgblack@eecs.umich.edu    uint64_t CWP = tc->readMiscReg(MISCREG_CWP);
2553415Sgblack@eecs.umich.edu    uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
2563415Sgblack@eecs.umich.edu    uint64_t GL = tc->readMiscReg(MISCREG_GL);
2573415Sgblack@eecs.umich.edu    uint64_t PC = tc->readPC();
2583415Sgblack@eecs.umich.edu    uint64_t NPC = tc->readNextPC();
2593415Sgblack@eecs.umich.edu
2603415Sgblack@eecs.umich.edu    //Increment the trap level
2613415Sgblack@eecs.umich.edu    TL++;
2623415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TL, TL);
2633415Sgblack@eecs.umich.edu
2643415Sgblack@eecs.umich.edu    //Save off state
2653415Sgblack@eecs.umich.edu
2663415Sgblack@eecs.umich.edu    //set TSTATE.gl to gl
2673415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 42, 40, GL);
2683415Sgblack@eecs.umich.edu    //set TSTATE.ccr to ccr
2693415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 39, 32, CCR);
2703415Sgblack@eecs.umich.edu    //set TSTATE.asi to asi
2713415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 31, 24, ASI);
2723415Sgblack@eecs.umich.edu    //set TSTATE.pstate to pstate
2733415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 20, 8, PSTATE);
2743415Sgblack@eecs.umich.edu    //set TSTATE.cwp to cwp
2753415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 4, 0, CWP);
2763415Sgblack@eecs.umich.edu
2773415Sgblack@eecs.umich.edu    //Write back TSTATE
2783415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TSTATE, TSTATE);
2793415Sgblack@eecs.umich.edu
2803415Sgblack@eecs.umich.edu    //set TPC to PC
2813415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TPC, PC);
2823415Sgblack@eecs.umich.edu    //set TNPC to NPC
2833415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TNPC, NPC);
2843415Sgblack@eecs.umich.edu
2853415Sgblack@eecs.umich.edu    //set HTSTATE.hpstate to hpstate
2863415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
2873415Sgblack@eecs.umich.edu
2883415Sgblack@eecs.umich.edu    //TT = trap type;
2893415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TT, tt);
2903415Sgblack@eecs.umich.edu
2913415Sgblack@eecs.umich.edu    //Update the global register level
2923415Sgblack@eecs.umich.edu    if(1/*We're delivering the trap in priveleged mode*/)
2933415Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL));
2943415Sgblack@eecs.umich.edu    else
2953415Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxPGL));
2963415Sgblack@eecs.umich.edu
2973415Sgblack@eecs.umich.edu    //PSTATE.mm is unchanged
2983415Sgblack@eecs.umich.edu    //PSTATE.pef = whether or not an fpu is present
2993415Sgblack@eecs.umich.edu    //XXX We'll say there's one present, even though there aren't
3003415Sgblack@eecs.umich.edu    //implementations for a decent number of the instructions
3013415Sgblack@eecs.umich.edu    PSTATE |= (1 << 4);
3023415Sgblack@eecs.umich.edu    //PSTATE.am = 0
3033415Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 3);
3043415Sgblack@eecs.umich.edu    if(1/*We're delivering the trap in priveleged mode*/)
3053415Sgblack@eecs.umich.edu    {
3063415Sgblack@eecs.umich.edu        //PSTATE.priv = 1
3073415Sgblack@eecs.umich.edu        PSTATE |= (1 << 2);
3083415Sgblack@eecs.umich.edu        //PSTATE.cle = PSTATE.tle
3093415Sgblack@eecs.umich.edu        replaceBits(PSTATE, 9, 9, PSTATE >> 8);
3103415Sgblack@eecs.umich.edu    }
3113415Sgblack@eecs.umich.edu    else
3123415Sgblack@eecs.umich.edu    {
3133415Sgblack@eecs.umich.edu        //PSTATE.priv = 0
3143415Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 2);
3153415Sgblack@eecs.umich.edu        //PSTATE.cle = 0
3163415Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 9);
3173415Sgblack@eecs.umich.edu    }
3183415Sgblack@eecs.umich.edu    //PSTATE.ie = 0
3193415Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 1);
3203415Sgblack@eecs.umich.edu    //PSTATE.tle is unchanged
3213415Sgblack@eecs.umich.edu    //PSTATE.tct = 0
3223415Sgblack@eecs.umich.edu    //XXX Where exactly is this field?
3233415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
3243415Sgblack@eecs.umich.edu
3253415Sgblack@eecs.umich.edu    if(0/*We're delivering the trap in hyperprivileged mode*/)
3263415Sgblack@eecs.umich.edu    {
3273415Sgblack@eecs.umich.edu        //HPSTATE.red = 0
3283415Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 5);
3293415Sgblack@eecs.umich.edu        //HPSTATE.hpriv = 1
3303415Sgblack@eecs.umich.edu        HPSTATE |= (1 << 2);
3313415Sgblack@eecs.umich.edu        //HPSTATE.ibe = 0
3323415Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 10);
3333415Sgblack@eecs.umich.edu        //HPSTATE.tlz is unchanged
3343415Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
3353415Sgblack@eecs.umich.edu    }
3363415Sgblack@eecs.umich.edu
3373415Sgblack@eecs.umich.edu    bool changedCWP = true;
3383415Sgblack@eecs.umich.edu    if(tt == 0x24)
3393415Sgblack@eecs.umich.edu    {
3403415Sgblack@eecs.umich.edu        warn("Incrementing the CWP by 1\n");
3413415Sgblack@eecs.umich.edu        CWP++;
3423415Sgblack@eecs.umich.edu    }
3433415Sgblack@eecs.umich.edu    else if(0x80 <= tt && tt <= 0xbf)
3443415Sgblack@eecs.umich.edu    {
3453415Sgblack@eecs.umich.edu        warn("Incrementing the CWP by %d\n", CANSAVE + 2);
3463415Sgblack@eecs.umich.edu        CWP += (CANSAVE + 2);
3473415Sgblack@eecs.umich.edu    }
3483415Sgblack@eecs.umich.edu    else if(0xc0 <= tt && tt <= 0xff)
3493415Sgblack@eecs.umich.edu    {
3503415Sgblack@eecs.umich.edu        warn("Decrementing the CWP by 1\n");
3513415Sgblack@eecs.umich.edu        CWP--;
3523415Sgblack@eecs.umich.edu    }
3533415Sgblack@eecs.umich.edu    else
3543415Sgblack@eecs.umich.edu        changedCWP = false;
3553415Sgblack@eecs.umich.edu    if(changedCWP)
3563415Sgblack@eecs.umich.edu    {
3573415Sgblack@eecs.umich.edu        CWP = (CWP + NWindows) % NWindows;
3583415Sgblack@eecs.umich.edu        tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
3593415Sgblack@eecs.umich.edu    }
3603415Sgblack@eecs.umich.edu}
3613415Sgblack@eecs.umich.edu
3622221SN/A#if FULL_SYSTEM
3632221SN/A
3642680Sktlim@umich.eduvoid SparcFault::invoke(ThreadContext * tc)
3652221SN/A{
3662680Sktlim@umich.edu    FaultBase::invoke(tc);
3672223SN/A    countStat()++;
3682221SN/A
3692223SN/A    //Use the SPARC trap state machine
3702223SN/A    /*// exception restart address
3712680Sktlim@umich.edu    if (setRestartAddress() || !tc->inPalMode())
3722680Sktlim@umich.edu        tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc);
3732221SN/A
3742221SN/A    if (skipFaultingInstruction()) {
3752221SN/A        // traps...  skip faulting instruction.
3762680Sktlim@umich.edu        tc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
3772680Sktlim@umich.edu                   tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
3782221SN/A    }
3792221SN/A
3802680Sktlim@umich.edu    if (!tc->inPalMode())
3812680Sktlim@umich.edu        AlphaISA::swap_palshadow(&(tc->regs), true);
3822221SN/A
3832680Sktlim@umich.edu    tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect();
3842680Sktlim@umich.edu    tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/
3852221SN/A}
3862221SN/A
3872612SN/A#endif
3882612SN/A
3892612SN/A#if !FULL_SYSTEM
3902612SN/A
3912680Sktlim@umich.eduvoid TrapInstruction::invoke(ThreadContext * tc)
3922523SN/A{
3932719Sktlim@umich.edu    // Should be handled in ISA.
3942523SN/A}
3952523SN/A
3963415Sgblack@eecs.umich.eduvoid SpillNNormal::invoke(ThreadContext *tc)
3973415Sgblack@eecs.umich.edu{
3983415Sgblack@eecs.umich.edu    warn("I'm in a spill trap\n");
3993415Sgblack@eecs.umich.edu    doNormalFault(tc, trapType());
4003415Sgblack@eecs.umich.edu
4013415Sgblack@eecs.umich.edu    Process *p = tc->getProcessPtr();
4023415Sgblack@eecs.umich.edu
4033415Sgblack@eecs.umich.edu    //This will only work in faults from a SparcLiveProcess
4043415Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
4053415Sgblack@eecs.umich.edu    assert(lp);
4063415Sgblack@eecs.umich.edu
4073415Sgblack@eecs.umich.edu    //Then adjust the PC and NPC
4083415Sgblack@eecs.umich.edu    Addr spillStart = lp->readSpillStart();
4093415Sgblack@eecs.umich.edu    tc->setPC(spillStart);
4103415Sgblack@eecs.umich.edu    tc->setNextPC(spillStart + sizeof(MachInst));
4113415Sgblack@eecs.umich.edu    tc->setNextNPC(spillStart + 2*sizeof(MachInst));
4123415Sgblack@eecs.umich.edu}
4133415Sgblack@eecs.umich.edu
4143415Sgblack@eecs.umich.eduvoid FillNNormal::invoke(ThreadContext *tc)
4153415Sgblack@eecs.umich.edu{
4163415Sgblack@eecs.umich.edu    warn("I'm in a fill trap\n");
4173415Sgblack@eecs.umich.edu    doNormalFault(tc, trapType());
4183415Sgblack@eecs.umich.edu
4193415Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
4203415Sgblack@eecs.umich.edu
4213415Sgblack@eecs.umich.edu    //This will only work in faults from a SparcLiveProcess
4223415Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
4233415Sgblack@eecs.umich.edu    assert(lp);
4243415Sgblack@eecs.umich.edu
4253415Sgblack@eecs.umich.edu    //The adjust the PC and NPC
4263415Sgblack@eecs.umich.edu    Addr fillStart = lp->readFillStart();
4273415Sgblack@eecs.umich.edu    tc->setPC(fillStart);
4283415Sgblack@eecs.umich.edu    tc->setNextPC(fillStart + sizeof(MachInst));
4293415Sgblack@eecs.umich.edu    tc->setNextNPC(fillStart + 2*sizeof(MachInst));
4303415Sgblack@eecs.umich.edu}
4313415Sgblack@eecs.umich.edu
4322800Ssaidi@eecs.umich.eduvoid PageTableFault::invoke(ThreadContext *tc)
4332800Ssaidi@eecs.umich.edu{
4342800Ssaidi@eecs.umich.edu    Process *p = tc->getProcessPtr();
4352800Ssaidi@eecs.umich.edu
4362800Ssaidi@eecs.umich.edu    // address is higher than the stack region or in the current stack region
4372800Ssaidi@eecs.umich.edu    if (vaddr > p->stack_base || vaddr > p->stack_min)
4382800Ssaidi@eecs.umich.edu        FaultBase::invoke(tc);
4392800Ssaidi@eecs.umich.edu
4402800Ssaidi@eecs.umich.edu    // We've accessed the next page
4412800Ssaidi@eecs.umich.edu    if (vaddr > p->stack_min - PageBytes) {
4422800Ssaidi@eecs.umich.edu        p->stack_min -= PageBytes;
4432800Ssaidi@eecs.umich.edu        if (p->stack_base - p->stack_min > 8*1024*1024)
4442800Ssaidi@eecs.umich.edu            fatal("Over max stack size for one thread\n");
4452800Ssaidi@eecs.umich.edu        p->pTable->allocate(p->stack_min, PageBytes);
4462800Ssaidi@eecs.umich.edu        warn("Increasing stack size by one page.");
4472800Ssaidi@eecs.umich.edu    } else {
4482800Ssaidi@eecs.umich.edu        FaultBase::invoke(tc);
4492800Ssaidi@eecs.umich.edu    }
4502800Ssaidi@eecs.umich.edu}
4513415Sgblack@eecs.umich.edu
4522221SN/A#endif
4532221SN/A
4542223SN/A} // namespace SparcISA
4552221SN/A
456