faults.cc revision 3523
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 "base/bitfield.hh"
373415Sgblack@eecs.umich.edu#include "base/trace.hh"
383523Sgblack@eecs.umich.edu#include "config/full_system.hh"
393415Sgblack@eecs.umich.edu#include "cpu/base.hh"
402680Sktlim@umich.edu#include "cpu/thread_context.hh"
412800Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
423523Sgblack@eecs.umich.edu#include "arch/sparc/process.hh"
433415Sgblack@eecs.umich.edu#include "mem/page_table.hh"
442800Ssaidi@eecs.umich.edu#include "sim/process.hh"
452800Ssaidi@eecs.umich.edu#endif
462221SN/A
473415Sgblack@eecs.umich.eduusing namespace std;
483415Sgblack@eecs.umich.edu
492223SN/Anamespace SparcISA
502221SN/A{
512221SN/A
522223SN/AFaultName     InternalProcessorError::_name = "intprocerr";
532223SN/ATrapType      InternalProcessorError::_trapType = 0x029;
542223SN/AFaultPriority InternalProcessorError::_priority = 4;
552223SN/AFaultStat     InternalProcessorError::_count;
562221SN/A
572223SN/AFaultName     MemAddressNotAligned::_name = "unalign";
582223SN/ATrapType      MemAddressNotAligned::_trapType = 0x034;
592223SN/AFaultPriority MemAddressNotAligned::_priority = 10;
602223SN/AFaultStat     MemAddressNotAligned::_count;
612221SN/A
622223SN/AFaultName     PowerOnReset::_name = "pow_reset";
632223SN/ATrapType      PowerOnReset::_trapType = 0x001;
642223SN/AFaultPriority PowerOnReset::_priority = 0;
652223SN/AFaultStat     PowerOnReset::_count;
662221SN/A
672223SN/AFaultName     WatchDogReset::_name = "watch_dog_reset";
682223SN/ATrapType      WatchDogReset::_trapType = 0x002;
692223SN/AFaultPriority WatchDogReset::_priority = 1;
702223SN/AFaultStat     WatchDogReset::_count;
712221SN/A
722223SN/AFaultName     ExternallyInitiatedReset::_name = "extern_reset";
732223SN/ATrapType      ExternallyInitiatedReset::_trapType = 0x003;
742223SN/AFaultPriority ExternallyInitiatedReset::_priority = 1;
752223SN/AFaultStat     ExternallyInitiatedReset::_count;
762221SN/A
772223SN/AFaultName     SoftwareInitiatedReset::_name = "software_reset";
782223SN/ATrapType      SoftwareInitiatedReset::_trapType = 0x004;
792223SN/AFaultPriority SoftwareInitiatedReset::_priority = 1;
802223SN/AFaultStat     SoftwareInitiatedReset::_count;
812221SN/A
822223SN/AFaultName     REDStateException::_name = "red_counte";
832223SN/ATrapType      REDStateException::_trapType = 0x005;
842223SN/AFaultPriority REDStateException::_priority = 1;
852223SN/AFaultStat     REDStateException::_count;
862221SN/A
872223SN/AFaultName     InstructionAccessException::_name = "inst_access";
882223SN/ATrapType      InstructionAccessException::_trapType = 0x008;
892223SN/AFaultPriority InstructionAccessException::_priority = 5;
902223SN/AFaultStat     InstructionAccessException::_count;
912221SN/A
922223SN/AFaultName     InstructionAccessMMUMiss::_name = "inst_mmu";
932223SN/ATrapType      InstructionAccessMMUMiss::_trapType = 0x009;
942223SN/AFaultPriority InstructionAccessMMUMiss::_priority = 2;
952223SN/AFaultStat     InstructionAccessMMUMiss::_count;
962221SN/A
972223SN/AFaultName     InstructionAccessError::_name = "inst_error";
982223SN/ATrapType      InstructionAccessError::_trapType = 0x00A;
992223SN/AFaultPriority InstructionAccessError::_priority = 3;
1002223SN/AFaultStat     InstructionAccessError::_count;
1012221SN/A
1022223SN/AFaultName     IllegalInstruction::_name = "illegal_inst";
1032223SN/ATrapType      IllegalInstruction::_trapType = 0x010;
1042223SN/AFaultPriority IllegalInstruction::_priority = 7;
1052223SN/AFaultStat     IllegalInstruction::_count;
1062221SN/A
1072469SN/AFaultName     PrivilegedOpcode::_name = "priv_opcode";
1082469SN/ATrapType      PrivilegedOpcode::_trapType = 0x011;
1092469SN/AFaultPriority PrivilegedOpcode::_priority = 6;
1102469SN/AFaultStat     PrivilegedOpcode::_count;
1112221SN/A
1122223SN/AFaultName     UnimplementedLDD::_name = "unimp_ldd";
1132223SN/ATrapType      UnimplementedLDD::_trapType = 0x012;
1142223SN/AFaultPriority UnimplementedLDD::_priority = 6;
1152223SN/AFaultStat     UnimplementedLDD::_count;
1162221SN/A
1172223SN/AFaultName     UnimplementedSTD::_name = "unimp_std";
1182223SN/ATrapType      UnimplementedSTD::_trapType = 0x013;
1192223SN/AFaultPriority UnimplementedSTD::_priority = 6;
1202223SN/AFaultStat     UnimplementedSTD::_count;
1212221SN/A
1222223SN/AFaultName     FpDisabled::_name = "fp_disabled";
1232223SN/ATrapType      FpDisabled::_trapType = 0x020;
1242223SN/AFaultPriority FpDisabled::_priority = 8;
1252223SN/AFaultStat     FpDisabled::_count;
1262221SN/A
1272223SN/AFaultName     FpExceptionIEEE754::_name = "fp_754";
1282223SN/ATrapType      FpExceptionIEEE754::_trapType = 0x021;
1292223SN/AFaultPriority FpExceptionIEEE754::_priority = 11;
1302223SN/AFaultStat     FpExceptionIEEE754::_count;
1312223SN/A
1322223SN/AFaultName     FpExceptionOther::_name = "fp_other";
1332223SN/ATrapType      FpExceptionOther::_trapType = 0x022;
1342223SN/AFaultPriority FpExceptionOther::_priority = 11;
1352223SN/AFaultStat     FpExceptionOther::_count;
1362223SN/A
1372223SN/AFaultName     TagOverflow::_name = "tag_overflow";
1382223SN/ATrapType      TagOverflow::_trapType = 0x023;
1392223SN/AFaultPriority TagOverflow::_priority = 14;
1402223SN/AFaultStat     TagOverflow::_count;
1412223SN/A
1422223SN/AFaultName     DivisionByZero::_name = "div_by_zero";
1432223SN/ATrapType      DivisionByZero::_trapType = 0x028;
1442223SN/AFaultPriority DivisionByZero::_priority = 15;
1452223SN/AFaultStat     DivisionByZero::_count;
1462223SN/A
1472223SN/AFaultName     DataAccessException::_name = "data_access";
1482223SN/ATrapType      DataAccessException::_trapType = 0x030;
1492223SN/AFaultPriority DataAccessException::_priority = 12;
1502223SN/AFaultStat     DataAccessException::_count;
1512223SN/A
1522223SN/AFaultName     DataAccessMMUMiss::_name = "data_mmu";
1532223SN/ATrapType      DataAccessMMUMiss::_trapType = 0x031;
1542223SN/AFaultPriority DataAccessMMUMiss::_priority = 12;
1552223SN/AFaultStat     DataAccessMMUMiss::_count;
1562223SN/A
1572223SN/AFaultName     DataAccessError::_name = "data_error";
1582223SN/ATrapType      DataAccessError::_trapType = 0x032;
1592223SN/AFaultPriority DataAccessError::_priority = 12;
1602223SN/AFaultStat     DataAccessError::_count;
1612223SN/A
1622223SN/AFaultName     DataAccessProtection::_name = "data_protection";
1632223SN/ATrapType      DataAccessProtection::_trapType = 0x033;
1642223SN/AFaultPriority DataAccessProtection::_priority = 12;
1652223SN/AFaultStat     DataAccessProtection::_count;
1662223SN/A
1672223SN/AFaultName     LDDFMemAddressNotAligned::_name = "unalign_lddf";
1682223SN/ATrapType      LDDFMemAddressNotAligned::_trapType = 0x035;
1692223SN/AFaultPriority LDDFMemAddressNotAligned::_priority = 10;
1702223SN/AFaultStat     LDDFMemAddressNotAligned::_count;
1712223SN/A
1722223SN/AFaultName     STDFMemAddressNotAligned::_name = "unalign_stdf";
1732223SN/ATrapType      STDFMemAddressNotAligned::_trapType = 0x036;
1742223SN/AFaultPriority STDFMemAddressNotAligned::_priority = 10;
1752223SN/AFaultStat     STDFMemAddressNotAligned::_count;
1762223SN/A
1772469SN/AFaultName     PrivilegedAction::_name = "priv_action";
1782469SN/ATrapType      PrivilegedAction::_trapType = 0x037;
1792469SN/AFaultPriority PrivilegedAction::_priority = 11;
1802469SN/AFaultStat     PrivilegedAction::_count;
1812223SN/A
1822223SN/AFaultName     LDQFMemAddressNotAligned::_name = "unalign_ldqf";
1832223SN/ATrapType      LDQFMemAddressNotAligned::_trapType = 0x038;
1842223SN/AFaultPriority LDQFMemAddressNotAligned::_priority = 10;
1852223SN/AFaultStat     LDQFMemAddressNotAligned::_count;
1862223SN/A
1872223SN/AFaultName     STQFMemAddressNotAligned::_name = "unalign_stqf";
1882223SN/ATrapType      STQFMemAddressNotAligned::_trapType = 0x039;
1892223SN/AFaultPriority STQFMemAddressNotAligned::_priority = 10;
1902223SN/AFaultStat     STQFMemAddressNotAligned::_count;
1912223SN/A
1922223SN/AFaultName     AsyncDataError::_name = "async_data";
1932223SN/ATrapType      AsyncDataError::_trapType = 0x040;
1942223SN/AFaultPriority AsyncDataError::_priority = 2;
1952223SN/AFaultStat     AsyncDataError::_count;
1962223SN/A
1972223SN/AFaultName     CleanWindow::_name = "clean_win";
1982527SN/ATrapType      CleanWindow::_trapType = 0x024;
1992223SN/AFaultPriority CleanWindow::_priority = 10;
2002223SN/AFaultStat     CleanWindow::_count;
2012223SN/A
2022527SN/A//The enumerated faults
2032527SN/A
2042223SN/AFaultName     InterruptLevelN::_name = "interrupt_n";
2052223SN/ATrapType      InterruptLevelN::_baseTrapType = 0x041;
2062223SN/AFaultStat     InterruptLevelN::_count;
2072223SN/A
2082223SN/AFaultName     SpillNNormal::_name = "spill_n_normal";
2092223SN/ATrapType      SpillNNormal::_baseTrapType = 0x080;
2102223SN/AFaultPriority SpillNNormal::_priority = 9;
2112223SN/AFaultStat     SpillNNormal::_count;
2122223SN/A
2132223SN/AFaultName     SpillNOther::_name = "spill_n_other";
2142223SN/ATrapType      SpillNOther::_baseTrapType = 0x0A0;
2152223SN/AFaultPriority SpillNOther::_priority = 9;
2162223SN/AFaultStat     SpillNOther::_count;
2172223SN/A
2182223SN/AFaultName     FillNNormal::_name = "fill_n_normal";
2192223SN/ATrapType      FillNNormal::_baseTrapType = 0x0C0;
2202223SN/AFaultPriority FillNNormal::_priority = 9;
2212223SN/AFaultStat     FillNNormal::_count;
2222223SN/A
2232223SN/AFaultName     FillNOther::_name = "fill_n_other";
2242223SN/ATrapType      FillNOther::_baseTrapType = 0x0E0;
2252223SN/AFaultPriority FillNOther::_priority = 9;
2262223SN/AFaultStat     FillNOther::_count;
2272223SN/A
2282223SN/AFaultName     TrapInstruction::_name = "trap_inst_n";
2292223SN/ATrapType      TrapInstruction::_baseTrapType = 0x100;
2302223SN/AFaultPriority TrapInstruction::_priority = 16;
2312223SN/AFaultStat     TrapInstruction::_count;
2322223SN/A
2332800Ssaidi@eecs.umich.edu#if !FULL_SYSTEM
2342800Ssaidi@eecs.umich.eduFaultName PageTableFault::_name = "page_table_fault";
2352800Ssaidi@eecs.umich.eduTrapType PageTableFault::_trapType = 0x0000;
2362800Ssaidi@eecs.umich.eduFaultPriority PageTableFault::_priority = 0;
2372800Ssaidi@eecs.umich.eduFaultStat PageTableFault::_count;
2382800Ssaidi@eecs.umich.edu#endif
2392800Ssaidi@eecs.umich.edu
2403415Sgblack@eecs.umich.edu/**
2413415Sgblack@eecs.umich.edu * This sets everything up for a normal trap except for actually jumping to
2423415Sgblack@eecs.umich.edu * the handler. It will need to be expanded to include the state machine in
2433415Sgblack@eecs.umich.edu * the manual. Right now it assumes that traps will always be to the
2443415Sgblack@eecs.umich.edu * privileged level.
2453415Sgblack@eecs.umich.edu */
2463415Sgblack@eecs.umich.edu
2473415Sgblack@eecs.umich.eduvoid doNormalFault(ThreadContext *tc, TrapType tt)
2483415Sgblack@eecs.umich.edu{
2493415Sgblack@eecs.umich.edu    uint64_t TL = tc->readMiscReg(MISCREG_TL);
2503415Sgblack@eecs.umich.edu    uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE);
2513415Sgblack@eecs.umich.edu    uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE);
2523415Sgblack@eecs.umich.edu    uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
2533415Sgblack@eecs.umich.edu    uint64_t CCR = tc->readMiscReg(MISCREG_CCR);
2543415Sgblack@eecs.umich.edu    uint64_t ASI = tc->readMiscReg(MISCREG_ASI);
2553415Sgblack@eecs.umich.edu    uint64_t CWP = tc->readMiscReg(MISCREG_CWP);
2563415Sgblack@eecs.umich.edu    uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
2573415Sgblack@eecs.umich.edu    uint64_t GL = tc->readMiscReg(MISCREG_GL);
2583415Sgblack@eecs.umich.edu    uint64_t PC = tc->readPC();
2593415Sgblack@eecs.umich.edu    uint64_t NPC = tc->readNextPC();
2603415Sgblack@eecs.umich.edu
2613415Sgblack@eecs.umich.edu    //Increment the trap level
2623415Sgblack@eecs.umich.edu    TL++;
2633415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TL, TL);
2643415Sgblack@eecs.umich.edu
2653415Sgblack@eecs.umich.edu    //Save off state
2663415Sgblack@eecs.umich.edu
2673415Sgblack@eecs.umich.edu    //set TSTATE.gl to gl
2683415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 42, 40, GL);
2693415Sgblack@eecs.umich.edu    //set TSTATE.ccr to ccr
2703415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 39, 32, CCR);
2713415Sgblack@eecs.umich.edu    //set TSTATE.asi to asi
2723415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 31, 24, ASI);
2733415Sgblack@eecs.umich.edu    //set TSTATE.pstate to pstate
2743415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 20, 8, PSTATE);
2753415Sgblack@eecs.umich.edu    //set TSTATE.cwp to cwp
2763415Sgblack@eecs.umich.edu    replaceBits(TSTATE, 4, 0, CWP);
2773415Sgblack@eecs.umich.edu
2783415Sgblack@eecs.umich.edu    //Write back TSTATE
2793415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TSTATE, TSTATE);
2803415Sgblack@eecs.umich.edu
2813415Sgblack@eecs.umich.edu    //set TPC to PC
2823415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TPC, PC);
2833415Sgblack@eecs.umich.edu    //set TNPC to NPC
2843415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TNPC, NPC);
2853415Sgblack@eecs.umich.edu
2863415Sgblack@eecs.umich.edu    //set HTSTATE.hpstate to hpstate
2873415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
2883415Sgblack@eecs.umich.edu
2893415Sgblack@eecs.umich.edu    //TT = trap type;
2903415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TT, tt);
2913415Sgblack@eecs.umich.edu
2923415Sgblack@eecs.umich.edu    //Update the global register level
2933415Sgblack@eecs.umich.edu    if(1/*We're delivering the trap in priveleged mode*/)
2943415Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL));
2953415Sgblack@eecs.umich.edu    else
2963415Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxPGL));
2973415Sgblack@eecs.umich.edu
2983415Sgblack@eecs.umich.edu    //PSTATE.mm is unchanged
2993415Sgblack@eecs.umich.edu    //PSTATE.pef = whether or not an fpu is present
3003415Sgblack@eecs.umich.edu    //XXX We'll say there's one present, even though there aren't
3013415Sgblack@eecs.umich.edu    //implementations for a decent number of the instructions
3023415Sgblack@eecs.umich.edu    PSTATE |= (1 << 4);
3033415Sgblack@eecs.umich.edu    //PSTATE.am = 0
3043415Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 3);
3053415Sgblack@eecs.umich.edu    if(1/*We're delivering the trap in priveleged mode*/)
3063415Sgblack@eecs.umich.edu    {
3073415Sgblack@eecs.umich.edu        //PSTATE.priv = 1
3083415Sgblack@eecs.umich.edu        PSTATE |= (1 << 2);
3093415Sgblack@eecs.umich.edu        //PSTATE.cle = PSTATE.tle
3103415Sgblack@eecs.umich.edu        replaceBits(PSTATE, 9, 9, PSTATE >> 8);
3113415Sgblack@eecs.umich.edu    }
3123415Sgblack@eecs.umich.edu    else
3133415Sgblack@eecs.umich.edu    {
3143415Sgblack@eecs.umich.edu        //PSTATE.priv = 0
3153415Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 2);
3163415Sgblack@eecs.umich.edu        //PSTATE.cle = 0
3173415Sgblack@eecs.umich.edu        PSTATE &= ~(1 << 9);
3183415Sgblack@eecs.umich.edu    }
3193415Sgblack@eecs.umich.edu    //PSTATE.ie = 0
3203415Sgblack@eecs.umich.edu    PSTATE &= ~(1 << 1);
3213415Sgblack@eecs.umich.edu    //PSTATE.tle is unchanged
3223415Sgblack@eecs.umich.edu    //PSTATE.tct = 0
3233415Sgblack@eecs.umich.edu    //XXX Where exactly is this field?
3243415Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_PSTATE, PSTATE);
3253415Sgblack@eecs.umich.edu
3263415Sgblack@eecs.umich.edu    if(0/*We're delivering the trap in hyperprivileged mode*/)
3273415Sgblack@eecs.umich.edu    {
3283415Sgblack@eecs.umich.edu        //HPSTATE.red = 0
3293415Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 5);
3303415Sgblack@eecs.umich.edu        //HPSTATE.hpriv = 1
3313415Sgblack@eecs.umich.edu        HPSTATE |= (1 << 2);
3323415Sgblack@eecs.umich.edu        //HPSTATE.ibe = 0
3333415Sgblack@eecs.umich.edu        HPSTATE &= ~(1 << 10);
3343415Sgblack@eecs.umich.edu        //HPSTATE.tlz is unchanged
3353415Sgblack@eecs.umich.edu        tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
3363415Sgblack@eecs.umich.edu    }
3373415Sgblack@eecs.umich.edu
3383415Sgblack@eecs.umich.edu    bool changedCWP = true;
3393415Sgblack@eecs.umich.edu    if(tt == 0x24)
3403415Sgblack@eecs.umich.edu        CWP++;
3413415Sgblack@eecs.umich.edu    else if(0x80 <= tt && tt <= 0xbf)
3423415Sgblack@eecs.umich.edu        CWP += (CANSAVE + 2);
3433415Sgblack@eecs.umich.edu    else if(0xc0 <= tt && tt <= 0xff)
3443415Sgblack@eecs.umich.edu        CWP--;
3453415Sgblack@eecs.umich.edu    else
3463415Sgblack@eecs.umich.edu        changedCWP = false;
3473420Sgblack@eecs.umich.edu
3483415Sgblack@eecs.umich.edu    if(changedCWP)
3493415Sgblack@eecs.umich.edu    {
3503415Sgblack@eecs.umich.edu        CWP = (CWP + NWindows) % NWindows;
3513415Sgblack@eecs.umich.edu        tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
3523415Sgblack@eecs.umich.edu    }
3533415Sgblack@eecs.umich.edu}
3543415Sgblack@eecs.umich.edu
3552221SN/A#if FULL_SYSTEM
3562221SN/A
3572680Sktlim@umich.eduvoid SparcFault::invoke(ThreadContext * tc)
3582221SN/A{
3592680Sktlim@umich.edu    FaultBase::invoke(tc);
3602223SN/A    countStat()++;
3612221SN/A
3622223SN/A    //Use the SPARC trap state machine
3632221SN/A}
3642221SN/A
3653523Sgblack@eecs.umich.eduvoid PowerOnReset::invoke(ThreadContext * tc)
3663523Sgblack@eecs.umich.edu{
3673523Sgblack@eecs.umich.edu    //For SPARC, when a system is first started, there is a power
3683523Sgblack@eecs.umich.edu    //on reset Trap which sets the processor into the following state.
3693523Sgblack@eecs.umich.edu    //Bits that aren't set aren't defined on startup.
3703523Sgblack@eecs.umich.edu    /*
3713523Sgblack@eecs.umich.edu    tl = MaxTL;
3723523Sgblack@eecs.umich.edu    gl = MaxGL;
3733523Sgblack@eecs.umich.edu
3743523Sgblack@eecs.umich.edu    tickFields.counter = 0; //The TICK register is unreadable bya
3753523Sgblack@eecs.umich.edu    tickFields.npt = 1; //The TICK register is unreadable by by !priv
3763523Sgblack@eecs.umich.edu
3773523Sgblack@eecs.umich.edu    softint = 0; // Clear all the soft interrupt bits
3783523Sgblack@eecs.umich.edu    tick_cmprFields.int_dis = 1; // disable timer compare interrupts
3793523Sgblack@eecs.umich.edu    tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
3803523Sgblack@eecs.umich.edu    stickFields.npt = 1; //The TICK register is unreadable by by !priv
3813523Sgblack@eecs.umich.edu    stick_cmprFields.int_dis = 1; // disable timer compare interrupts
3823523Sgblack@eecs.umich.edu    stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
3833523Sgblack@eecs.umich.edu
3843523Sgblack@eecs.umich.edu    tt[tl] = _trapType;
3853523Sgblack@eecs.umich.edu    pstate = 0; // fields 0 but pef
3863523Sgblack@eecs.umich.edu    pstateFields.pef = 1;
3873523Sgblack@eecs.umich.edu
3883523Sgblack@eecs.umich.edu    hpstate = 0;
3893523Sgblack@eecs.umich.edu    hpstateFields.red = 1;
3903523Sgblack@eecs.umich.edu    hpstateFields.hpriv = 1;
3913523Sgblack@eecs.umich.edu    hpstateFields.tlz = 0; // this is a guess
3923523Sgblack@eecs.umich.edu    hintp = 0; // no interrupts pending
3933523Sgblack@eecs.umich.edu    hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
3943523Sgblack@eecs.umich.edu    hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
3953523Sgblack@eecs.umich.edu    */
3963523Sgblack@eecs.umich.edu}
3973523Sgblack@eecs.umich.edu
3982612SN/A#endif
3992612SN/A
4002612SN/A#if !FULL_SYSTEM
4012612SN/A
4022680Sktlim@umich.eduvoid TrapInstruction::invoke(ThreadContext * tc)
4032523SN/A{
4042719Sktlim@umich.edu    // Should be handled in ISA.
4052523SN/A}
4062523SN/A
4073415Sgblack@eecs.umich.eduvoid SpillNNormal::invoke(ThreadContext *tc)
4083415Sgblack@eecs.umich.edu{
4093415Sgblack@eecs.umich.edu    doNormalFault(tc, trapType());
4103415Sgblack@eecs.umich.edu
4113415Sgblack@eecs.umich.edu    Process *p = tc->getProcessPtr();
4123415Sgblack@eecs.umich.edu
4133415Sgblack@eecs.umich.edu    //This will only work in faults from a SparcLiveProcess
4143415Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
4153415Sgblack@eecs.umich.edu    assert(lp);
4163415Sgblack@eecs.umich.edu
4173415Sgblack@eecs.umich.edu    //Then adjust the PC and NPC
4183415Sgblack@eecs.umich.edu    Addr spillStart = lp->readSpillStart();
4193415Sgblack@eecs.umich.edu    tc->setPC(spillStart);
4203415Sgblack@eecs.umich.edu    tc->setNextPC(spillStart + sizeof(MachInst));
4213415Sgblack@eecs.umich.edu    tc->setNextNPC(spillStart + 2*sizeof(MachInst));
4223415Sgblack@eecs.umich.edu}
4233415Sgblack@eecs.umich.edu
4243415Sgblack@eecs.umich.eduvoid FillNNormal::invoke(ThreadContext *tc)
4253415Sgblack@eecs.umich.edu{
4263415Sgblack@eecs.umich.edu    doNormalFault(tc, trapType());
4273415Sgblack@eecs.umich.edu
4283415Sgblack@eecs.umich.edu    Process * p = tc->getProcessPtr();
4293415Sgblack@eecs.umich.edu
4303415Sgblack@eecs.umich.edu    //This will only work in faults from a SparcLiveProcess
4313415Sgblack@eecs.umich.edu    SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
4323415Sgblack@eecs.umich.edu    assert(lp);
4333415Sgblack@eecs.umich.edu
4343415Sgblack@eecs.umich.edu    //The adjust the PC and NPC
4353415Sgblack@eecs.umich.edu    Addr fillStart = lp->readFillStart();
4363415Sgblack@eecs.umich.edu    tc->setPC(fillStart);
4373415Sgblack@eecs.umich.edu    tc->setNextPC(fillStart + sizeof(MachInst));
4383415Sgblack@eecs.umich.edu    tc->setNextNPC(fillStart + 2*sizeof(MachInst));
4393415Sgblack@eecs.umich.edu}
4403415Sgblack@eecs.umich.edu
4412800Ssaidi@eecs.umich.eduvoid PageTableFault::invoke(ThreadContext *tc)
4422800Ssaidi@eecs.umich.edu{
4432800Ssaidi@eecs.umich.edu    Process *p = tc->getProcessPtr();
4442800Ssaidi@eecs.umich.edu
4452800Ssaidi@eecs.umich.edu    // address is higher than the stack region or in the current stack region
4462800Ssaidi@eecs.umich.edu    if (vaddr > p->stack_base || vaddr > p->stack_min)
4472800Ssaidi@eecs.umich.edu        FaultBase::invoke(tc);
4482800Ssaidi@eecs.umich.edu
4492800Ssaidi@eecs.umich.edu    // We've accessed the next page
4502800Ssaidi@eecs.umich.edu    if (vaddr > p->stack_min - PageBytes) {
4512800Ssaidi@eecs.umich.edu        p->stack_min -= PageBytes;
4522800Ssaidi@eecs.umich.edu        if (p->stack_base - p->stack_min > 8*1024*1024)
4532800Ssaidi@eecs.umich.edu            fatal("Over max stack size for one thread\n");
4542800Ssaidi@eecs.umich.edu        p->pTable->allocate(p->stack_min, PageBytes);
4552800Ssaidi@eecs.umich.edu        warn("Increasing stack size by one page.");
4562800Ssaidi@eecs.umich.edu    } else {
4572800Ssaidi@eecs.umich.edu        FaultBase::invoke(tc);
4582800Ssaidi@eecs.umich.edu    }
4592800Ssaidi@eecs.umich.edu}
4603415Sgblack@eecs.umich.edu
4612221SN/A#endif
4622221SN/A
4632223SN/A} // namespace SparcISA
4642221SN/A
465