ua2005.cc revision 2982
12650Ssaidi@eecs.umich.edu/*
22650Ssaidi@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
32650Ssaidi@eecs.umich.edu * All rights reserved.
42650Ssaidi@eecs.umich.edu *
52650Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
62650Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are
72650Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright
82650Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
92650Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
102650Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
112650Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution;
122650Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its
132650Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from
142650Ssaidi@eecs.umich.edu * this software without specific prior written permission.
152650Ssaidi@eecs.umich.edu *
162650Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172650Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182650Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192650Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202650Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212650Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222650Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232650Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242650Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252650Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262650Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi
292650Ssaidi@eecs.umich.edu */
302650Ssaidi@eecs.umich.edu
312650Ssaidi@eecs.umich.edu#include "arch/sparc/regfile.hh"
322650Ssaidi@eecs.umich.edu
332650Ssaidi@eecs.umich.eduFault
342650Ssaidi@eecs.umich.eduSparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
352680Sktlim@umich.edu        ThreadContext *tc)
362650Ssaidi@eecs.umich.edu{
372650Ssaidi@eecs.umich.edu    int64_t time;
382650Ssaidi@eecs.umich.edu    SparcSystem *sys;
392650Ssaidi@eecs.umich.edu    switch (miscReg) {
402982Sstever@eecs.umich.edu        /* Full system only ASRs */
412650Ssaidi@eecs.umich.edu        case MISCREG_SOFTINT:
422650Ssaidi@eecs.umich.edu          if (isNonPriv())
432650Ssaidi@eecs.umich.edu              return new PrivilegedOpcode;
442650Ssaidi@eecs.umich.edu          // Check if we are going to interrupt because of something
452650Ssaidi@eecs.umich.edu          int oldLevel = InterruptLevel(softint);
462650Ssaidi@eecs.umich.edu          int newLevel = InterruptLevel(val);
472650Ssaidi@eecs.umich.edu          setReg(miscReg, val);
482650Ssaidi@eecs.umich.edu          if (newLevel > oldLevel)
492650Ssaidi@eecs.umich.edu              ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
502680Sktlim@umich.edu              //tc->getCpuPtr()->checkInterrupts = true;
512650Ssaidi@eecs.umich.edu          return NoFault;
522650Ssaidi@eecs.umich.edu
532650Ssaidi@eecs.umich.edu        case MISCREG_SOFTINT_CLR:
542680Sktlim@umich.edu          return setRegWithEffect(miscReg, ~val & softint, tc);
552650Ssaidi@eecs.umich.edu        case MISCREG_SOFTINT_SET:
562680Sktlim@umich.edu          return setRegWithEffect(miscReg, val | softint, tc);
572650Ssaidi@eecs.umich.edu
582650Ssaidi@eecs.umich.edu        case MISCREG_TICK_CMPR:
592650Ssaidi@eecs.umich.edu          if (isNonPriv())
602650Ssaidi@eecs.umich.edu              return new PrivilegedOpcode;
612651Ssaidi@eecs.umich.edu          if (tickCompare == NULL)
622680Sktlim@umich.edu              tickCompare = new TickCompareEvent(this, tc);
632650Ssaidi@eecs.umich.edu          setReg(miscReg, val);
642650Ssaidi@eecs.umich.edu          if (tick_cmprFields.int_dis && tickCompare.scheduled())
652650Ssaidi@eecs.umich.edu                  tickCompare.deschedule();
662650Ssaidi@eecs.umich.edu          time = tick_cmprFields.tick_cmpr - tickFields.counter;
672650Ssaidi@eecs.umich.edu          if (!tick_cmprFields.int_dis && time > 0)
682680Sktlim@umich.edu              tickCompare.schedule(time * tc->getCpuPtr()->cycles(1));
692650Ssaidi@eecs.umich.edu          return NoFault;
702650Ssaidi@eecs.umich.edu
712650Ssaidi@eecs.umich.edu        case MISCREG_STICK:
722650Ssaidi@eecs.umich.edu          if (isNonPriv())
732650Ssaidi@eecs.umich.edu              return new PrivilegedOpcode;
742650Ssaidi@eecs.umich.edu          if (isPriv())
752650Ssaidi@eecs.umich.edu              return new PrivilegedAction;
762680Sktlim@umich.edu          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
772650Ssaidi@eecs.umich.edu          assert(sys != NULL);
782650Ssaidi@eecs.umich.edu          sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
792650Ssaidi@eecs.umich.edu          stickFields.npt = val & Bit64 ? 1 : 0;
802650Ssaidi@eecs.umich.edu          return NoFault;
812650Ssaidi@eecs.umich.edu
822650Ssaidi@eecs.umich.edu        case MISCREG_STICK_CMPR:
832650Ssaidi@eecs.umich.edu          if (isNonPriv())
842650Ssaidi@eecs.umich.edu              return new PrivilegedOpcode;
852651Ssaidi@eecs.umich.edu          if (sTickCompare == NULL)
862680Sktlim@umich.edu              sTickCompare = new STickCompareEvent(this, tc);
872680Sktlim@umich.edu          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
882650Ssaidi@eecs.umich.edu          assert(sys != NULL);
892650Ssaidi@eecs.umich.edu          setReg(miscReg, val);
902650Ssaidi@eecs.umich.edu          if (stick_cmprFields.int_dis && sTickCompare.scheduled())
912650Ssaidi@eecs.umich.edu                  sTickCompare.deschedule();
922650Ssaidi@eecs.umich.edu          time = stick_cmprFields.tick_cmpr - sys->sysTick;
932650Ssaidi@eecs.umich.edu          if (!stick_cmprFields.int_dis && time > 0)
942650Ssaidi@eecs.umich.edu              sTickCompare.schedule(time * Clock::Int::ns);
952650Ssaidi@eecs.umich.edu          return NoFault;
962650Ssaidi@eecs.umich.edu
972982Sstever@eecs.umich.edu        /* Fullsystem only Priv registers. */
982650Ssaidi@eecs.umich.edu        case MISCREG_PIL:
992650Ssaidi@eecs.umich.edu          if (FULL_SYSTEM) {
1002650Ssaidi@eecs.umich.edu              setReg(miscReg, val);
1012680Sktlim@umich.edu              //tc->getCpuPtr()->checkInterrupts;
1022650Ssaidi@eecs.umich.edu               // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
1032650Ssaidi@eecs.umich.edu              return NoFault;
1042650Ssaidi@eecs.umich.edu          } else
1052650Ssaidi@eecs.umich.edu              panic("PIL not implemented for syscall emulation\n");
1062650Ssaidi@eecs.umich.edu
1072982Sstever@eecs.umich.edu        /* Hyper privileged registers */
1082650Ssaidi@eecs.umich.edu        case MISCREG_HPSTATE:
1092650Ssaidi@eecs.umich.edu        case MISCREG_HINTP:
1102650Ssaidi@eecs.umich.edu          setReg(miscReg, val);
1112650Ssaidi@eecs.umich.edu          return NoFault;
1122650Ssaidi@eecs.umich.edu        case MISCREG_HTSTATE:
1132650Ssaidi@eecs.umich.edu          if (tl == 0)
1142650Ssaidi@eecs.umich.edu              return new IllegalInstruction;
1152650Ssaidi@eecs.umich.edu          setReg(miscReg, val);
1162650Ssaidi@eecs.umich.edu          return NoFault;
1172650Ssaidi@eecs.umich.edu
1182650Ssaidi@eecs.umich.edu        case MISCREG_HTBA:
1192650Ssaidi@eecs.umich.edu          // clear lower 7 bits on writes.
1202650Ssaidi@eecs.umich.edu          setReg(miscReg, val & ULL(~0x7FFF));
1212650Ssaidi@eecs.umich.edu          return NoFault;
1222650Ssaidi@eecs.umich.edu
1232650Ssaidi@eecs.umich.edu        case MISCREG_STRAND_STS_REG:
1242650Ssaidi@eecs.umich.edu          setReg(miscReg, strandStatusReg);
1252650Ssaidi@eecs.umich.edu          return NoFault;
1262650Ssaidi@eecs.umich.edu        case MISCREG_HSTICK_CMPR:
1272650Ssaidi@eecs.umich.edu          if (isNonPriv())
1282650Ssaidi@eecs.umich.edu              return new PrivilegedOpcode;
1292651Ssaidi@eecs.umich.edu          if (hSTickCompare == NULL)
1302680Sktlim@umich.edu              hSTickCompare = new HSTickCompareEvent(this, tc);
1312680Sktlim@umich.edu          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
1322650Ssaidi@eecs.umich.edu          assert(sys != NULL);
1332650Ssaidi@eecs.umich.edu          setReg(miscReg, val);
1342650Ssaidi@eecs.umich.edu          if (hstick_cmprFields.int_dis && hSTickCompare.scheduled())
1352650Ssaidi@eecs.umich.edu                  hSTickCompare.deschedule();
1362650Ssaidi@eecs.umich.edu          int64_t time = hstick_cmprFields.tick_cmpr - sys->sysTick;
1372650Ssaidi@eecs.umich.edu          if (!hstick_cmprFields.int_dis && time > 0)
1382650Ssaidi@eecs.umich.edu              hSTickCompare.schedule(time * Clock::Int::ns);
1392650Ssaidi@eecs.umich.edu          return NoFault;
1402650Ssaidi@eecs.umich.edu        default:
1412650Ssaidi@eecs.umich.edu          return new IllegalInstruction;
1422650Ssaidi@eecs.umich.edu    }
1432650Ssaidi@eecs.umich.edu}
1442650Ssaidi@eecs.umich.edu
1452650Ssaidi@eecs.umich.eduMiscReg
1462680Sktlim@umich.eduMiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc)
1472650Ssaidi@eecs.umich.edu{
1482650Ssaidi@eecs.umich.edu    switch (miscReg) {
1492650Ssaidi@eecs.umich.edu
1502982Sstever@eecs.umich.edu        /* Privileged registers. */
1512650Ssaidi@eecs.umich.edu        case MISCREG_SOFTINT:
1522650Ssaidi@eecs.umich.edu           if (isNonPriv()) {
1532650Ssaidi@eecs.umich.edu               fault = new PrivilegedOpcode;
1542650Ssaidi@eecs.umich.edu               return 0;
1552650Ssaidi@eecs.umich.edu           }
1562650Ssaidi@eecs.umich.edu           return readReg(miscReg);
1572650Ssaidi@eecs.umich.edu        case MISCREG_TICK_CMPR:
1582650Ssaidi@eecs.umich.edu           if (isNonPriv()) {
1592650Ssaidi@eecs.umich.edu               fault =  new PrivilegedOpcode;
1602650Ssaidi@eecs.umich.edu               return 0;
1612650Ssaidi@eecs.umich.edu           }
1622650Ssaidi@eecs.umich.edu           return readReg(miscReg);
1632650Ssaidi@eecs.umich.edu        case MISCREG_STICK:
1642650Ssaidi@eecs.umich.edu          SparcSystem *sys;
1652650Ssaidi@eecs.umich.edu          if (stickFields.npt && !isNonPriv()) {
1662650Ssaidi@eecs.umich.edu              fault = new PrivilegedAction;
1672650Ssaidi@eecs.umich.edu              return 0;
1682650Ssaidi@eecs.umich.edu          }
1692680Sktlim@umich.edu          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
1702650Ssaidi@eecs.umich.edu          assert(sys != NULL);
1712650Ssaidi@eecs.umich.edu          return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63;
1722650Ssaidi@eecs.umich.edu        case MISCREG_STICK_CMPR:
1732650Ssaidi@eecs.umich.edu           if (isNonPriv()) {
1742650Ssaidi@eecs.umich.edu               fault =  new PrivilegedOpcode;
1752650Ssaidi@eecs.umich.edu               return 0;
1762650Ssaidi@eecs.umich.edu           }
1772650Ssaidi@eecs.umich.edu           return readReg(miscReg);
1782650Ssaidi@eecs.umich.edu
1792650Ssaidi@eecs.umich.edu
1802982Sstever@eecs.umich.edu        /* Hyper privileged registers */
1812650Ssaidi@eecs.umich.edu        case MISCREG_HPSTATE:
1822650Ssaidi@eecs.umich.edu        case MISCREG_HINTP:
1832650Ssaidi@eecs.umich.edu          return readReg(miscReg);
1842650Ssaidi@eecs.umich.edu        case MISCREG_HTSTATE:
1852650Ssaidi@eecs.umich.edu          if (tl == 0) {
1862650Ssaidi@eecs.umich.edu              fault = new IllegalInstruction;
1872650Ssaidi@eecs.umich.edu              return 0;
1882650Ssaidi@eecs.umich.edu          }
1892650Ssaidi@eecs.umich.edu          return readReg(miscReg);
1902650Ssaidi@eecs.umich.edu
1912650Ssaidi@eecs.umich.edu        case MISCREG_HTBA:
1922650Ssaidi@eecs.umich.edu          return readReg(miscReg) & ULL(~0x7FFF);
1932650Ssaidi@eecs.umich.edu        case MISCREG_HVER:
1942650Ssaidi@eecs.umich.edu          return NWindows | MaxTL << 8 | MaxGL << 16;
1952650Ssaidi@eecs.umich.edu        case MISCREG_STRAND_STS_REG:
1962650Ssaidi@eecs.umich.edu          return strandStatusReg;
1972650Ssaidi@eecs.umich.edu        case MISCREG_HSTICK_CMPR:
1982650Ssaidi@eecs.umich.edu          return hstick_cmpr;
1992650Ssaidi@eecs.umich.edu
2002650Ssaidi@eecs.umich.edu        default:
2012650Ssaidi@eecs.umich.edu          fault = new IllegalInstruction;
2022650Ssaidi@eecs.umich.edu          return 0;
2032650Ssaidi@eecs.umich.edu    }
2042650Ssaidi@eecs.umich.edu}
2052650Ssaidi@eecs.umich.edu
2062651Ssaidi@eecs.umich.eduvoid
2072680Sktlim@umich.eduMiscRegFile::processTickCompare(ThreadContext *tc)
2082651Ssaidi@eecs.umich.edu{
2092651Ssaidi@eecs.umich.edu    panic("tick compare not implemented\n");
2102651Ssaidi@eecs.umich.edu}
2112651Ssaidi@eecs.umich.edu
2122651Ssaidi@eecs.umich.eduvoid
2132680Sktlim@umich.eduMiscRegFile::processSTickCompare(ThreadContext *tc)
2142651Ssaidi@eecs.umich.edu{
2152651Ssaidi@eecs.umich.edu    panic("tick compare not implemented\n");
2162651Ssaidi@eecs.umich.edu}
2172651Ssaidi@eecs.umich.edu
2182651Ssaidi@eecs.umich.eduvoid
2192680Sktlim@umich.eduMiscRegFile::processHSTickCompare(ThreadContext *tc)
2202651Ssaidi@eecs.umich.edu{
2212651Ssaidi@eecs.umich.edu    panic("tick compare not implemented\n");
2222651Ssaidi@eecs.umich.edu}
2232650Ssaidi@eecs.umich.edu
2242650Ssaidi@eecs.umich.edu}; // namespace SparcISA
225