ua2005.cc revision 3891:5f37b870a627
112837Sgabeblack@google.com/*
212837Sgabeblack@google.com * Copyright (c) 2006 The Regents of The University of Michigan
312837Sgabeblack@google.com * All rights reserved.
412837Sgabeblack@google.com *
512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412837Sgabeblack@google.com * this software without specific prior written permission.
1512837Sgabeblack@google.com *
1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712837Sgabeblack@google.com *
2812837Sgabeblack@google.com * Authors: Ali Saidi
2912837Sgabeblack@google.com */
3012837Sgabeblack@google.com
3112954Sgabeblack@google.com#include "arch/sparc/miscregfile.hh"
3213140Sgabeblack@google.com#include "base/bitfield.hh"
3313238Sgabeblack@google.com#include "base/trace.hh"
3412837Sgabeblack@google.com#include "cpu/base.hh"
3512837Sgabeblack@google.com#include "cpu/thread_context.hh"
3613140Sgabeblack@google.com
3713140Sgabeblack@google.comusing namespace SparcISA;
3813140Sgabeblack@google.com
3913140Sgabeblack@google.comvoid
4013140Sgabeblack@google.comMiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
4113140Sgabeblack@google.com        ThreadContext *tc)
4213140Sgabeblack@google.com{
4312837Sgabeblack@google.com    int64_t time;
4412837Sgabeblack@google.com    switch (miscReg) {
4512837Sgabeblack@google.com        /* Full system only ASRs */
4613238Sgabeblack@google.com        case MISCREG_SOFTINT:
4713238Sgabeblack@google.com          // Check if we are going to interrupt because of something
4813238Sgabeblack@google.com          setReg(miscReg, val);
4913238Sgabeblack@google.com          tc->getCpuPtr()->checkInterrupts = true;
5013238Sgabeblack@google.com          warn("Writing to softint not really supported, writing: %#x\n", val);
5113238Sgabeblack@google.com          break;
5213238Sgabeblack@google.com
5313238Sgabeblack@google.com        case MISCREG_SOFTINT_CLR:
5413238Sgabeblack@google.com          return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc);
5513238Sgabeblack@google.com        case MISCREG_SOFTINT_SET:
5613238Sgabeblack@google.com          return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc);
5713238Sgabeblack@google.com
5812837Sgabeblack@google.com        case MISCREG_TICK_CMPR:
5912954Sgabeblack@google.com          if (tickCompare == NULL)
6013238Sgabeblack@google.com              tickCompare = new TickCompareEvent(this, tc);
6113238Sgabeblack@google.com          setReg(miscReg, val);
6213238Sgabeblack@google.com          if ((tick_cmpr & mask(63)) && tickCompare->scheduled())
6313238Sgabeblack@google.com                  tickCompare->deschedule();
6413238Sgabeblack@google.com          time = (tick_cmpr & mask(63)) - (tick & mask(63));
6513238Sgabeblack@google.com          if (!(tick_cmpr & ~mask(63)) && time > 0)
6613238Sgabeblack@google.com              tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
6713238Sgabeblack@google.com          panic("writing to TICK compare register %#X\n", val);
6813238Sgabeblack@google.com          break;
6913238Sgabeblack@google.com
7013238Sgabeblack@google.com        case MISCREG_STICK_CMPR:
7113238Sgabeblack@google.com          if (sTickCompare == NULL)
7212837Sgabeblack@google.com              sTickCompare = new STickCompareEvent(this, tc);
7312954Sgabeblack@google.com          setReg(miscReg, val);
7412837Sgabeblack@google.com          if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
7512837Sgabeblack@google.com                  sTickCompare->deschedule();
7612837Sgabeblack@google.com          time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
7712837Sgabeblack@google.com             tc->getCpuPtr()->instCount();
7812954Sgabeblack@google.com          if (!(stick_cmpr & ~mask(63)) && time > 0)
7912837Sgabeblack@google.com              sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick);
8012837Sgabeblack@google.com          DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
8112837Sgabeblack@google.com          break;
8212837Sgabeblack@google.com
8312837Sgabeblack@google.com        case MISCREG_PSTATE:
8412954Sgabeblack@google.com          if (val & ie && !(pstate & ie)) {
8512837Sgabeblack@google.com              tc->getCpuPtr()->checkInterrupts = true;
8612837Sgabeblack@google.com          }
8712837Sgabeblack@google.com          setReg(miscReg, val);
8812837Sgabeblack@google.com
8912837Sgabeblack@google.com        case MISCREG_PIL:
9012954Sgabeblack@google.com          if (val < pil) {
9112837Sgabeblack@google.com              tc->getCpuPtr()->checkInterrupts = true;
9212837Sgabeblack@google.com          }
9312837Sgabeblack@google.com          setReg(miscReg, val);
9412954Sgabeblack@google.com          break;
9512837Sgabeblack@google.com
9612954Sgabeblack@google.com        case MISCREG_HVER:
9712837Sgabeblack@google.com          panic("Shouldn't be writing HVER\n");
9812837Sgabeblack@google.com
9912837Sgabeblack@google.com        case MISCREG_HTBA:
10012954Sgabeblack@google.com          // clear lower 7 bits on writes.
10112837Sgabeblack@google.com          setReg(miscReg, val & ULL(~0x7FFF));
10212954Sgabeblack@google.com          break;
10312837Sgabeblack@google.com
10412837Sgabeblack@google.com        case MISCREG_QUEUE_CPU_MONDO_HEAD:
10512837Sgabeblack@google.com        case MISCREG_QUEUE_CPU_MONDO_TAIL:
10612954Sgabeblack@google.com        case MISCREG_QUEUE_DEV_MONDO_HEAD:
10712837Sgabeblack@google.com        case MISCREG_QUEUE_DEV_MONDO_TAIL:
10812954Sgabeblack@google.com        case MISCREG_QUEUE_RES_ERROR_HEAD:
10912837Sgabeblack@google.com        case MISCREG_QUEUE_RES_ERROR_TAIL:
11012837Sgabeblack@google.com        case MISCREG_QUEUE_NRES_ERROR_HEAD:
11112837Sgabeblack@google.com        case MISCREG_QUEUE_NRES_ERROR_TAIL:
11212954Sgabeblack@google.com          setReg(miscReg, val);
11312837Sgabeblack@google.com          tc->getCpuPtr()->checkInterrupts = true;
11412954Sgabeblack@google.com          break;
11512837Sgabeblack@google.com
11612837Sgabeblack@google.com        case MISCREG_HSTICK_CMPR:
11712837Sgabeblack@google.com          if (hSTickCompare == NULL)
11812954Sgabeblack@google.com              hSTickCompare = new HSTickCompareEvent(this, tc);
11912837Sgabeblack@google.com          setReg(miscReg, val);
12012954Sgabeblack@google.com          if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
12112837Sgabeblack@google.com                hSTickCompare->deschedule();
12212837Sgabeblack@google.com          time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
12312837Sgabeblack@google.com             tc->getCpuPtr()->instCount();
12412954Sgabeblack@google.com          if (!(hstick_cmpr & ~mask(63)) && time > 0)
12512837Sgabeblack@google.com              hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1));
12612954Sgabeblack@google.com          DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
12712837Sgabeblack@google.com          break;
12812837Sgabeblack@google.com
12912837Sgabeblack@google.com        case MISCREG_HPSTATE:
13012954Sgabeblack@google.com          // T1000 spec says impl. dependent val must always be 1
13112837Sgabeblack@google.com          setReg(miscReg, val | id);
13212954Sgabeblack@google.com          break;
13312837Sgabeblack@google.com        case MISCREG_HTSTATE:
13412837Sgabeblack@google.com        case MISCREG_STRAND_STS_REG:
13512837Sgabeblack@google.com          setReg(miscReg, val);
13612954Sgabeblack@google.com          break;
13712837Sgabeblack@google.com
13812954Sgabeblack@google.com        default:
13912837Sgabeblack@google.com          panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
14012837Sgabeblack@google.com    }
14112837Sgabeblack@google.com}
14212954Sgabeblack@google.com
14312954Sgabeblack@google.comMiscReg
14412837Sgabeblack@google.comMiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc)
14512954Sgabeblack@google.com{
14612837Sgabeblack@google.com    switch (miscReg) {
14712837Sgabeblack@google.com      /* Privileged registers. */
14812837Sgabeblack@google.com      case MISCREG_QUEUE_CPU_MONDO_HEAD:
14912954Sgabeblack@google.com      case MISCREG_QUEUE_CPU_MONDO_TAIL:
15012837Sgabeblack@google.com      case MISCREG_QUEUE_DEV_MONDO_HEAD:
15112954Sgabeblack@google.com      case MISCREG_QUEUE_DEV_MONDO_TAIL:
15212837Sgabeblack@google.com      case MISCREG_QUEUE_RES_ERROR_HEAD:
15312837Sgabeblack@google.com      case MISCREG_QUEUE_RES_ERROR_TAIL:
15412837Sgabeblack@google.com      case MISCREG_QUEUE_NRES_ERROR_HEAD:
15512954Sgabeblack@google.com      case MISCREG_QUEUE_NRES_ERROR_TAIL:
15612954Sgabeblack@google.com      case MISCREG_SOFTINT:
15712837Sgabeblack@google.com      case MISCREG_TICK_CMPR:
15812954Sgabeblack@google.com      case MISCREG_STICK_CMPR:
15912837Sgabeblack@google.com      case MISCREG_PIL:
16012837Sgabeblack@google.com      case MISCREG_HPSTATE:
16112929Sgabeblack@google.com      case MISCREG_HINTP:
16212929Sgabeblack@google.com      case MISCREG_HTSTATE:
16312929Sgabeblack@google.com      case MISCREG_STRAND_STS_REG:
16413189Sgabeblack@google.com      case MISCREG_HSTICK_CMPR:
16512929Sgabeblack@google.com        return readReg(miscReg) ;
16612929Sgabeblack@google.com
16712837Sgabeblack@google.com      case MISCREG_HTBA:
16812837Sgabeblack@google.com        return readReg(miscReg) & ULL(~0x7FFF);
16912837Sgabeblack@google.com      case MISCREG_HVER:
17012954Sgabeblack@google.com        return NWindows | MaxTL << 8 | MaxGL << 16;
17112837Sgabeblack@google.com
17212837Sgabeblack@google.com      default:
17312837Sgabeblack@google.com        panic("Invalid read to FS misc register\n");
17412954Sgabeblack@google.com    }
17512837Sgabeblack@google.com}
17612954Sgabeblack@google.com/*
17712837Sgabeblack@google.com        In Niagra STICK==TICK so this isn't needed
17812837Sgabeblack@google.com        case MISCREG_STICK:
17912837Sgabeblack@google.com          SparcSystem *sys;
18012954Sgabeblack@google.com          sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
18112837Sgabeblack@google.com          assert(sys != NULL);
18212954Sgabeblack@google.com          return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
18312837Sgabeblack@google.com*/
18412837Sgabeblack@google.com
18512837Sgabeblack@google.com
18612954Sgabeblack@google.com
18712837Sgabeblack@google.comvoid
18812954Sgabeblack@google.comMiscRegFile::processTickCompare(ThreadContext *tc)
18912837Sgabeblack@google.com{
19012837Sgabeblack@google.com    panic("tick compare not implemented\n");
19112837Sgabeblack@google.com}
19212954Sgabeblack@google.com
19312837Sgabeblack@google.comvoid
19412954Sgabeblack@google.comMiscRegFile::processSTickCompare(ThreadContext *tc)
19512837Sgabeblack@google.com{
19612837Sgabeblack@google.com    // since our microcode instructions take two cycles we need to check if
19712837Sgabeblack@google.com    // we're actually at the correct cycle or we need to wait a little while
19812954Sgabeblack@google.com    // more
19912837Sgabeblack@google.com    int ticks;
20012954Sgabeblack@google.com    ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
20112837Sgabeblack@google.com            tc->getCpuPtr()->instCount();
20212837Sgabeblack@google.com    assert(ticks >= 0 && "stick compare missed interrupt cycle");
20312837Sgabeblack@google.com
20412954Sgabeblack@google.com    if (ticks == 0) {
20512837Sgabeblack@google.com        DPRINTF(Timer, "STick compare cycle reached at %#x\n",
20612954Sgabeblack@google.com                (stick_cmpr & mask(63)));
20712837Sgabeblack@google.com        tc->getCpuPtr()->checkInterrupts = true;
20812837Sgabeblack@google.com        softint |= ULL(1) << 16;
20912837Sgabeblack@google.com    } else
21012954Sgabeblack@google.com        sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
21112837Sgabeblack@google.com}
21212954Sgabeblack@google.com
21312837Sgabeblack@google.comvoid
21412837Sgabeblack@google.comMiscRegFile::processHSTickCompare(ThreadContext *tc)
21512837Sgabeblack@google.com{
21612954Sgabeblack@google.com    // since our microcode instructions take two cycles we need to check if
21712837Sgabeblack@google.com    // we're actually at the correct cycle or we need to wait a little while
21812954Sgabeblack@google.com    // more
21912837Sgabeblack@google.com    int ticks;
22012837Sgabeblack@google.com    ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
22112837Sgabeblack@google.com            tc->getCpuPtr()->instCount();
22212954Sgabeblack@google.com    assert(ticks >= 0 && "hstick compare missed interrupt cycle");
22312837Sgabeblack@google.com
22412954Sgabeblack@google.com    if (ticks == 0) {
22512837Sgabeblack@google.com        DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
22612837Sgabeblack@google.com                (stick_cmpr & mask(63)));
22712837Sgabeblack@google.com        tc->getCpuPtr()->checkInterrupts = true;
22812954Sgabeblack@google.com        // Need to do something to cause interrupt to happen here !!! @todo
22912837Sgabeblack@google.com    } else
23012954Sgabeblack@google.com        sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick);
23112837Sgabeblack@google.com}
23212837Sgabeblack@google.com
23312837Sgabeblack@google.com