ua2005.cc revision 3894:60a7b0a3602f
11689SN/A/*
22325SN/A * Copyright (c) 2006 The Regents of The University of Michigan
31689SN/A * All rights reserved.
41689SN/A *
51689SN/A * Redistribution and use in source and binary forms, with or without
61689SN/A * modification, are permitted provided that the following conditions are
71689SN/A * met: redistributions of source code must retain the above copyright
81689SN/A * notice, this list of conditions and the following disclaimer;
91689SN/A * redistributions in binary form must reproduce the above copyright
101689SN/A * notice, this list of conditions and the following disclaimer in the
111689SN/A * documentation and/or other materials provided with the distribution;
121689SN/A * neither the name of the copyright holders nor the names of its
131689SN/A * contributors may be used to endorse or promote products derived from
141689SN/A * this software without specific prior written permission.
151689SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi
292756Sksewell@umich.edu */
301689SN/A
311689SN/A#include "arch/sparc/miscregfile.hh"
321858SN/A#include "base/bitfield.hh"
332733Sktlim@umich.edu#include "base/trace.hh"
341858SN/A#include "cpu/base.hh"
351858SN/A#include "cpu/thread_context.hh"
362356SN/A
371060SN/Ausing namespace SparcISA;
381060SN/A
391060SN/Avoid
401060SN/AMiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
411060SN/A                                ThreadContext *tc)
422325SN/A{
432683Sktlim@umich.edu    int64_t time;
442680Sktlim@umich.edu    switch (miscReg) {
452817Sksewell@umich.edu        /* Full system only ASRs */
461717SN/A      case MISCREG_SOFTINT:
471060SN/A        // Check if we are going to interrupt because of something
484167Sbinkertn@umich.edu        setReg(miscReg, val);
492292SN/A        tc->getCpuPtr()->post_interrupt(soft_interrupt);
502292SN/A        warn("Writing to softint not really supported, writing: %#x\n", val);
512794Sktlim@umich.edu        break;
522794Sktlim@umich.edu
532794Sktlim@umich.edu      case MISCREG_SOFTINT_CLR:
542794Sktlim@umich.edu        return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc);
551060SN/A      case MISCREG_SOFTINT_SET:
562669Sktlim@umich.edu        return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc);
571060SN/A
582733Sktlim@umich.edu      case MISCREG_TICK_CMPR:
592292SN/A        if (tickCompare == NULL)
601060SN/A            tickCompare = new TickCompareEvent(this, tc);
611060SN/A        setReg(miscReg, val);
621060SN/A        if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
632292SN/A            tickCompare->deschedule();
642733Sktlim@umich.edu        time = (tick_cmpr & mask(63)) - (tick & mask(63));
652292SN/A        if (!(tick_cmpr & ~mask(63)) && time > 0)
662292SN/A            tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
672292SN/A        panic("writing to TICK compare register %#X\n", val);
682292SN/A        break;
691060SN/A
701755SN/A      case MISCREG_STICK_CMPR:
711060SN/A        if (sTickCompare == NULL)
721060SN/A            sTickCompare = new STickCompareEvent(this, tc);
731060SN/A        setReg(miscReg, val);
741060SN/A        if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
751060SN/A            sTickCompare->deschedule();
761060SN/A        time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
771755SN/A            tc->getCpuPtr()->instCount();
781060SN/A        if (!(stick_cmpr & ~mask(63)) && time > 0)
791060SN/A            sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick);
801060SN/A        DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
811060SN/A        break;
821060SN/A
831060SN/A      case MISCREG_PSTATE:
841755SN/A        if (val & ie && !(pstate & ie)) {
851060SN/A            tc->getCpuPtr()->checkInterrupts = true;
864873Sstever@eecs.umich.edu        }
871060SN/A        setReg(miscReg, val);
881060SN/A
891060SN/A      case MISCREG_PIL:
902829Sksewell@umich.edu        if (val < pil) {
913221Sktlim@umich.edu            tc->getCpuPtr()->checkInterrupts = true;
922829Sksewell@umich.edu        }
932829Sksewell@umich.edu        setReg(miscReg, val);
942829Sksewell@umich.edu        break;
952829Sksewell@umich.edu
962829Sksewell@umich.edu      case MISCREG_HVER:
972829Sksewell@umich.edu        panic("Shouldn't be writing HVER\n");
982829Sksewell@umich.edu
992829Sksewell@umich.edu      case MISCREG_HTBA:
1002829Sksewell@umich.edu        // clear lower 7 bits on writes.
1012829Sksewell@umich.edu        setReg(miscReg, val & ULL(~0x7FFF));
1022829Sksewell@umich.edu        break;
1032829Sksewell@umich.edu
1042829Sksewell@umich.edu      case MISCREG_QUEUE_CPU_MONDO_HEAD:
1052829Sksewell@umich.edu      case MISCREG_QUEUE_CPU_MONDO_TAIL:
1062829Sksewell@umich.edu      case MISCREG_QUEUE_DEV_MONDO_HEAD:
1072829Sksewell@umich.edu      case MISCREG_QUEUE_DEV_MONDO_TAIL:
1082829Sksewell@umich.edu      case MISCREG_QUEUE_RES_ERROR_HEAD:
1092829Sksewell@umich.edu      case MISCREG_QUEUE_RES_ERROR_TAIL:
1102829Sksewell@umich.edu      case MISCREG_QUEUE_NRES_ERROR_HEAD:
1112829Sksewell@umich.edu      case MISCREG_QUEUE_NRES_ERROR_TAIL:
1122829Sksewell@umich.edu        setReg(miscReg, val);
1132829Sksewell@umich.edu        tc->getCpuPtr()->checkInterrupts = true;
1142829Sksewell@umich.edu        break;
1154873Sstever@eecs.umich.edu
1162829Sksewell@umich.edu      case MISCREG_HSTICK_CMPR:
1172829Sksewell@umich.edu        if (hSTickCompare == NULL)
1182829Sksewell@umich.edu            hSTickCompare = new HSTickCompareEvent(this, tc);
1192875Sksewell@umich.edu        setReg(miscReg, val);
1203859Sbinkertn@umich.edu        if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
1212875Sksewell@umich.edu            hSTickCompare->deschedule();
1222875Sksewell@umich.edu        time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
1232875Sksewell@umich.edu            tc->getCpuPtr()->instCount();
1242875Sksewell@umich.edu        if (!(hstick_cmpr & ~mask(63)) && time > 0)
1252875Sksewell@umich.edu            hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1));
1262875Sksewell@umich.edu        DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
1273859Sbinkertn@umich.edu        break;
1282875Sksewell@umich.edu
1292875Sksewell@umich.edu      case MISCREG_HPSTATE:
1302875Sksewell@umich.edu        // T1000 spec says impl. dependent val must always be 1
1313859Sbinkertn@umich.edu        setReg(miscReg, val | id);
1322875Sksewell@umich.edu        break;
1332875Sksewell@umich.edu      case MISCREG_HTSTATE:
1342875Sksewell@umich.edu      case MISCREG_STRAND_STS_REG:
1352875Sksewell@umich.edu        setReg(miscReg, val);
1362875Sksewell@umich.edu        break;
1372875Sksewell@umich.edu
1382875Sksewell@umich.edu      default:
1393221Sktlim@umich.edu        panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
1403221Sktlim@umich.edu    }
1412875Sksewell@umich.edu}
1422875Sksewell@umich.edu
1432875Sksewell@umich.eduMiscReg
1442875Sksewell@umich.eduMiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc)
1452875Sksewell@umich.edu{
1462875Sksewell@umich.edu    switch (miscReg) {
1474873Sstever@eecs.umich.edu        /* Privileged registers. */
1482875Sksewell@umich.edu      case MISCREG_QUEUE_CPU_MONDO_HEAD:
1492875Sksewell@umich.edu      case MISCREG_QUEUE_CPU_MONDO_TAIL:
1502875Sksewell@umich.edu      case MISCREG_QUEUE_DEV_MONDO_HEAD:
1514329Sktlim@umich.edu      case MISCREG_QUEUE_DEV_MONDO_TAIL:
1522733Sktlim@umich.edu      case MISCREG_QUEUE_RES_ERROR_HEAD:
1533781Sgblack@eecs.umich.edu      case MISCREG_QUEUE_RES_ERROR_TAIL:
1543781Sgblack@eecs.umich.edu      case MISCREG_QUEUE_NRES_ERROR_HEAD:
1553781Sgblack@eecs.umich.edu      case MISCREG_QUEUE_NRES_ERROR_TAIL:
1563781Sgblack@eecs.umich.edu      case MISCREG_SOFTINT:
1571060SN/A      case MISCREG_TICK_CMPR:
1582292SN/A      case MISCREG_STICK_CMPR:
1594329Sktlim@umich.edu      case MISCREG_PIL:
1604329Sktlim@umich.edu      case MISCREG_HPSTATE:
1614329Sktlim@umich.edu      case MISCREG_HINTP:
1624329Sktlim@umich.edu      case MISCREG_HTSTATE:
1634329Sktlim@umich.edu      case MISCREG_STRAND_STS_REG:
1641060SN/A      case MISCREG_HSTICK_CMPR:
1654329Sktlim@umich.edu        return readReg(miscReg) ;
1664329Sktlim@umich.edu
1671060SN/A      case MISCREG_HTBA:
1682831Sksewell@umich.edu        return readReg(miscReg) & ULL(~0x7FFF);
1692292SN/A      case MISCREG_HVER:
1702292SN/A        return NWindows | MaxTL << 8 | MaxGL << 16;
1711060SN/A
1724329Sktlim@umich.edu      default:
1734329Sktlim@umich.edu        panic("Invalid read to FS misc register\n");
1742292SN/A    }
1752292SN/A}
1761060SN/A/*
1772831Sksewell@umich.edu  In Niagra STICK==TICK so this isn't needed
1782292SN/A  case MISCREG_STICK:
1792292SN/A  SparcSystem *sys;
1802292SN/A  sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
1812292SN/A  assert(sys != NULL);
1821060SN/A  return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
1832873Sktlim@umich.edu*/
1842873Sktlim@umich.edu
1852873Sktlim@umich.edu
1862873Sktlim@umich.edu
1872873Sktlim@umich.eduvoid
1882873Sktlim@umich.eduMiscRegFile::processTickCompare(ThreadContext *tc)
1892873Sktlim@umich.edu{
1902873Sktlim@umich.edu    panic("tick compare not implemented\n");
1911060SN/A}
1921060SN/A
1931858SN/Avoid
1942292SN/AMiscRegFile::processSTickCompare(ThreadContext *tc)
1951060SN/A{
1961060SN/A    // since our microcode instructions take two cycles we need to check if
1972843Sktlim@umich.edu    // we're actually at the correct cycle or we need to wait a little while
1982316SN/A    // more
1992316SN/A    int ticks;
2001060SN/A    ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
2013221Sktlim@umich.edu        tc->getCpuPtr()->instCount();
2023221Sktlim@umich.edu    assert(ticks >= 0 && "stick compare missed interrupt cycle");
2033221Sktlim@umich.edu
2043221Sktlim@umich.edu    if (ticks == 0) {
2053221Sktlim@umich.edu        DPRINTF(Timer, "STick compare cycle reached at %#x\n",
2061681SN/A                (stick_cmpr & mask(63)));
2074598Sbinkertn@umich.edu        tc->getCpuPtr()->post_interrupt(soft_interrupt);
2082794Sktlim@umich.edu        tc->getCpuPtr()->checkInterrupts = true;
2092316SN/A        softint |= ULL(1) << 16;
2102316SN/A    } else
2112316SN/A        sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
2122316SN/A}
2132316SN/A
2144598Sbinkertn@umich.eduvoid
2154598Sbinkertn@umich.eduMiscRegFile::processHSTickCompare(ThreadContext *tc)
2164598Sbinkertn@umich.edu{
2172794Sktlim@umich.edu    // since our microcode instructions take two cycles we need to check if
2182316SN/A    // we're actually at the correct cycle or we need to wait a little while
2191858SN/A    // more
2202292SN/A    int ticks;
2212292SN/A    ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
2221681SN/A        tc->getCpuPtr()->instCount();
2231681SN/A    assert(ticks >= 0 && "hstick compare missed interrupt cycle");
2242325SN/A
2252325SN/A    if (ticks == 0) {
2262325SN/A        DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
2271060SN/A                (stick_cmpr & mask(63)));
2282292SN/A        tc->getCpuPtr()->post_interrupt(hstick_match);
2292292SN/A        tc->getCpuPtr()->checkInterrupts = true;
2302292SN/A        // Need to do something to cause interrupt to happen here !!! @todo
2312292SN/A    } else
2322292SN/A        sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
2332292SN/A}
2341060SN/A
2351060SN/A