ua2005.cc revision 5531
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.
272650Ssaidi@eecs.umich.edu */
282650Ssaidi@eecs.umich.edu
294194Ssaidi@eecs.umich.edu#include "arch/sparc/kernel_stats.hh"
303817Ssaidi@eecs.umich.edu#include "arch/sparc/miscregfile.hh"
313817Ssaidi@eecs.umich.edu#include "base/bitfield.hh"
323817Ssaidi@eecs.umich.edu#include "base/trace.hh"
333817Ssaidi@eecs.umich.edu#include "cpu/base.hh"
343817Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh"
354194Ssaidi@eecs.umich.edu#include "sim/system.hh"
362650Ssaidi@eecs.umich.edu
373817Ssaidi@eecs.umich.eduusing namespace SparcISA;
383817Ssaidi@eecs.umich.edu
394103Ssaidi@eecs.umich.edu
404103Ssaidi@eecs.umich.eduvoid
414103Ssaidi@eecs.umich.eduMiscRegFile::checkSoftInt(ThreadContext *tc)
424103Ssaidi@eecs.umich.edu{
435531Snate@binkert.org    BaseCPU *cpu = tc->getCpuPtr();
445531Snate@binkert.org
454103Ssaidi@eecs.umich.edu    // If PIL < 14, copy over the tm and sm bits
464103Ssaidi@eecs.umich.edu    if (pil < 14 && softint & 0x10000)
475531Snate@binkert.org        cpu->post_interrupt(IT_SOFT_INT, 16);
484103Ssaidi@eecs.umich.edu    else
495531Snate@binkert.org        cpu->clear_interrupt(IT_SOFT_INT, 16);
504103Ssaidi@eecs.umich.edu    if (pil < 14 && softint & 0x1)
515531Snate@binkert.org        cpu->post_interrupt(IT_SOFT_INT, 0);
524103Ssaidi@eecs.umich.edu    else
535531Snate@binkert.org        cpu->clear_interrupt(IT_SOFT_INT, 0);
544103Ssaidi@eecs.umich.edu
554103Ssaidi@eecs.umich.edu    // Copy over any of the other bits that are set
564103Ssaidi@eecs.umich.edu    for (int bit = 15; bit > 0; --bit) {
574103Ssaidi@eecs.umich.edu        if (1 << bit & softint && bit > pil)
585531Snate@binkert.org            cpu->post_interrupt(IT_SOFT_INT, bit);
594103Ssaidi@eecs.umich.edu        else
605531Snate@binkert.org            cpu->clear_interrupt(IT_SOFT_INT, bit);
614103Ssaidi@eecs.umich.edu    }
624103Ssaidi@eecs.umich.edu}
634103Ssaidi@eecs.umich.edu
644103Ssaidi@eecs.umich.edu
653817Ssaidi@eecs.umich.eduvoid
664185Ssaidi@eecs.umich.eduMiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
672650Ssaidi@eecs.umich.edu{
685531Snate@binkert.org    BaseCPU *cpu = tc->getCpuPtr();
695531Snate@binkert.org
702650Ssaidi@eecs.umich.edu    int64_t time;
712650Ssaidi@eecs.umich.edu    switch (miscReg) {
722982Sstever@eecs.umich.edu        /* Full system only ASRs */
733919Shsul@eecs.umich.edu      case MISCREG_SOFTINT:
744172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);;
754103Ssaidi@eecs.umich.edu        checkSoftInt(tc);
763919Shsul@eecs.umich.edu        break;
773919Shsul@eecs.umich.edu      case MISCREG_SOFTINT_CLR:
784172Ssaidi@eecs.umich.edu        return setReg(MISCREG_SOFTINT, ~val & softint, tc);
793919Shsul@eecs.umich.edu      case MISCREG_SOFTINT_SET:
804172Ssaidi@eecs.umich.edu        return setReg(MISCREG_SOFTINT, val | softint, tc);
812650Ssaidi@eecs.umich.edu
823919Shsul@eecs.umich.edu      case MISCREG_TICK_CMPR:
833919Shsul@eecs.umich.edu        if (tickCompare == NULL)
843919Shsul@eecs.umich.edu            tickCompare = new TickCompareEvent(this, tc);
854172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
864103Ssaidi@eecs.umich.edu        if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
873919Shsul@eecs.umich.edu            tickCompare->deschedule();
883919Shsul@eecs.umich.edu        time = (tick_cmpr & mask(63)) - (tick & mask(63));
894103Ssaidi@eecs.umich.edu        if (!(tick_cmpr & ~mask(63)) && time > 0) {
904103Ssaidi@eecs.umich.edu            if (tickCompare->scheduled())
914103Ssaidi@eecs.umich.edu                tickCompare->deschedule();
925531Snate@binkert.org            tickCompare->schedule(time * cpu->ticks(1));
934103Ssaidi@eecs.umich.edu        }
943919Shsul@eecs.umich.edu        panic("writing to TICK compare register %#X\n", val);
953919Shsul@eecs.umich.edu        break;
962650Ssaidi@eecs.umich.edu
973919Shsul@eecs.umich.edu      case MISCREG_STICK_CMPR:
983919Shsul@eecs.umich.edu        if (sTickCompare == NULL)
993919Shsul@eecs.umich.edu            sTickCompare = new STickCompareEvent(this, tc);
1004172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1013919Shsul@eecs.umich.edu        if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
1023919Shsul@eecs.umich.edu            sTickCompare->deschedule();
1033919Shsul@eecs.umich.edu        time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
1045531Snate@binkert.org            cpu->instCount();
1054103Ssaidi@eecs.umich.edu        if (!(stick_cmpr & ~mask(63)) && time > 0) {
1064103Ssaidi@eecs.umich.edu            if (sTickCompare->scheduled())
1074103Ssaidi@eecs.umich.edu                sTickCompare->deschedule();
1085531Snate@binkert.org            sTickCompare->schedule(time * cpu->ticks(1) + curTick);
1094103Ssaidi@eecs.umich.edu        }
1103919Shsul@eecs.umich.edu        DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
1113919Shsul@eecs.umich.edu        break;
1122650Ssaidi@eecs.umich.edu
1133919Shsul@eecs.umich.edu      case MISCREG_PSTATE:
1144172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1153827Shsul@eecs.umich.edu
1163919Shsul@eecs.umich.edu      case MISCREG_PIL:
1174172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1184103Ssaidi@eecs.umich.edu        checkSoftInt(tc);
1193919Shsul@eecs.umich.edu        break;
1202650Ssaidi@eecs.umich.edu
1213919Shsul@eecs.umich.edu      case MISCREG_HVER:
1223919Shsul@eecs.umich.edu        panic("Shouldn't be writing HVER\n");
1232650Ssaidi@eecs.umich.edu
1243921Shsul@eecs.umich.edu      case MISCREG_HINTP:
1254172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1264103Ssaidi@eecs.umich.edu        if (hintp)
1275531Snate@binkert.org            cpu->post_interrupt(IT_HINTP, 0);
1284103Ssaidi@eecs.umich.edu        else
1295531Snate@binkert.org            cpu->clear_interrupt(IT_HINTP, 0);
1304103Ssaidi@eecs.umich.edu        break;
1313921Shsul@eecs.umich.edu
1323919Shsul@eecs.umich.edu      case MISCREG_HTBA:
1333919Shsul@eecs.umich.edu        // clear lower 7 bits on writes.
1344172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val & ULL(~0x7FFF));
1353919Shsul@eecs.umich.edu        break;
1362650Ssaidi@eecs.umich.edu
1373919Shsul@eecs.umich.edu      case MISCREG_QUEUE_CPU_MONDO_HEAD:
1383919Shsul@eecs.umich.edu      case MISCREG_QUEUE_CPU_MONDO_TAIL:
1394172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1404103Ssaidi@eecs.umich.edu        if (cpu_mondo_head != cpu_mondo_tail)
1415531Snate@binkert.org            cpu->post_interrupt(IT_CPU_MONDO, 0);
1424103Ssaidi@eecs.umich.edu        else
1435531Snate@binkert.org            cpu->clear_interrupt(IT_CPU_MONDO, 0);
1444103Ssaidi@eecs.umich.edu        break;
1453919Shsul@eecs.umich.edu      case MISCREG_QUEUE_DEV_MONDO_HEAD:
1463919Shsul@eecs.umich.edu      case MISCREG_QUEUE_DEV_MONDO_TAIL:
1474172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1484103Ssaidi@eecs.umich.edu        if (dev_mondo_head != dev_mondo_tail)
1495531Snate@binkert.org            cpu->post_interrupt(IT_DEV_MONDO, 0);
1504103Ssaidi@eecs.umich.edu        else
1515531Snate@binkert.org            cpu->clear_interrupt(IT_DEV_MONDO, 0);
1524103Ssaidi@eecs.umich.edu        break;
1533919Shsul@eecs.umich.edu      case MISCREG_QUEUE_RES_ERROR_HEAD:
1543919Shsul@eecs.umich.edu      case MISCREG_QUEUE_RES_ERROR_TAIL:
1554172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1564103Ssaidi@eecs.umich.edu        if (res_error_head != res_error_tail)
1575531Snate@binkert.org            cpu->post_interrupt(IT_RES_ERROR, 0);
1584103Ssaidi@eecs.umich.edu        else
1595531Snate@binkert.org            cpu->clear_interrupt(IT_RES_ERROR, 0);
1604103Ssaidi@eecs.umich.edu        break;
1613919Shsul@eecs.umich.edu      case MISCREG_QUEUE_NRES_ERROR_HEAD:
1623919Shsul@eecs.umich.edu      case MISCREG_QUEUE_NRES_ERROR_TAIL:
1634172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1644103Ssaidi@eecs.umich.edu        // This one doesn't have an interrupt to report to the guest OS
1653919Shsul@eecs.umich.edu        break;
1663828Shsul@eecs.umich.edu
1673919Shsul@eecs.umich.edu      case MISCREG_HSTICK_CMPR:
1683919Shsul@eecs.umich.edu        if (hSTickCompare == NULL)
1693919Shsul@eecs.umich.edu            hSTickCompare = new HSTickCompareEvent(this, tc);
1704172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1713919Shsul@eecs.umich.edu        if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
1723919Shsul@eecs.umich.edu            hSTickCompare->deschedule();
1733919Shsul@eecs.umich.edu        time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
1745531Snate@binkert.org            cpu->instCount();
1754103Ssaidi@eecs.umich.edu        if (!(hstick_cmpr & ~mask(63)) && time > 0) {
1764103Ssaidi@eecs.umich.edu            if (hSTickCompare->scheduled())
1774103Ssaidi@eecs.umich.edu                hSTickCompare->deschedule();
1785531Snate@binkert.org            hSTickCompare->schedule(curTick + time * cpu->ticks(1));
1794103Ssaidi@eecs.umich.edu        }
1803919Shsul@eecs.umich.edu        DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
1813919Shsul@eecs.umich.edu        break;
1823817Ssaidi@eecs.umich.edu
1833919Shsul@eecs.umich.edu      case MISCREG_HPSTATE:
1843919Shsul@eecs.umich.edu        // T1000 spec says impl. dependent val must always be 1
1854172Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val | HPSTATE::id);
1864103Ssaidi@eecs.umich.edu#if FULL_SYSTEM
1874103Ssaidi@eecs.umich.edu        if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
1885531Snate@binkert.org            cpu->post_interrupt(IT_TRAP_LEVEL_ZERO, 0);
1894103Ssaidi@eecs.umich.edu        else
1905531Snate@binkert.org            cpu->clear_interrupt(IT_TRAP_LEVEL_ZERO, 0);
1914103Ssaidi@eecs.umich.edu#endif
1923919Shsul@eecs.umich.edu        break;
1933919Shsul@eecs.umich.edu      case MISCREG_HTSTATE:
1944194Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, val);
1954194Ssaidi@eecs.umich.edu        break;
1964194Ssaidi@eecs.umich.edu
1973919Shsul@eecs.umich.edu      case MISCREG_STRAND_STS_REG:
1984194Ssaidi@eecs.umich.edu        if (bits(val,2,2))
1994194Ssaidi@eecs.umich.edu            panic("No support for setting spec_en bit\n");
2004194Ssaidi@eecs.umich.edu        setRegNoEffect(miscReg, bits(val,0,0));
2014194Ssaidi@eecs.umich.edu        if (!bits(val,0,0)) {
2024216Ssaidi@eecs.umich.edu            DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
2034194Ssaidi@eecs.umich.edu            // Time to go to sleep
2044194Ssaidi@eecs.umich.edu            tc->suspend();
2054194Ssaidi@eecs.umich.edu            if (tc->getKernelStats())
2064194Ssaidi@eecs.umich.edu                tc->getKernelStats()->quiesce();
2075531Snate@binkert.org        }
2083919Shsul@eecs.umich.edu        break;
2093817Ssaidi@eecs.umich.edu
2103919Shsul@eecs.umich.edu      default:
2115531Snate@binkert.org        panic("Invalid write to FS misc register %s\n",
2125531Snate@binkert.org              getMiscRegName(miscReg));
2132650Ssaidi@eecs.umich.edu    }
2142650Ssaidi@eecs.umich.edu}
2152650Ssaidi@eecs.umich.edu
2162650Ssaidi@eecs.umich.eduMiscReg
2174185Ssaidi@eecs.umich.eduMiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
2182650Ssaidi@eecs.umich.edu{
2194194Ssaidi@eecs.umich.edu    uint64_t temp;
2204194Ssaidi@eecs.umich.edu
2212650Ssaidi@eecs.umich.edu    switch (miscReg) {
2223919Shsul@eecs.umich.edu        /* Privileged registers. */
2233825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_CPU_MONDO_HEAD:
2243825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_CPU_MONDO_TAIL:
2253825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_DEV_MONDO_HEAD:
2263825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_DEV_MONDO_TAIL:
2273825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_RES_ERROR_HEAD:
2283825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_RES_ERROR_TAIL:
2293825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_NRES_ERROR_HEAD:
2303825Ssaidi@eecs.umich.edu      case MISCREG_QUEUE_NRES_ERROR_TAIL:
2313825Ssaidi@eecs.umich.edu      case MISCREG_SOFTINT:
2323825Ssaidi@eecs.umich.edu      case MISCREG_TICK_CMPR:
2333825Ssaidi@eecs.umich.edu      case MISCREG_STICK_CMPR:
2343825Ssaidi@eecs.umich.edu      case MISCREG_PIL:
2353825Ssaidi@eecs.umich.edu      case MISCREG_HPSTATE:
2363825Ssaidi@eecs.umich.edu      case MISCREG_HINTP:
2373825Ssaidi@eecs.umich.edu      case MISCREG_HTSTATE:
2383825Ssaidi@eecs.umich.edu      case MISCREG_HSTICK_CMPR:
2394172Ssaidi@eecs.umich.edu        return readRegNoEffect(miscReg) ;
2402650Ssaidi@eecs.umich.edu
2413825Ssaidi@eecs.umich.edu      case MISCREG_HTBA:
2424172Ssaidi@eecs.umich.edu        return readRegNoEffect(miscReg) & ULL(~0x7FFF);
2433825Ssaidi@eecs.umich.edu      case MISCREG_HVER:
2444207Ssaidi@eecs.umich.edu        // XXX set to match Legion
2454207Ssaidi@eecs.umich.edu        return ULL(0x3e) << 48 |
2464207Ssaidi@eecs.umich.edu               ULL(0x23) << 32 |
2474207Ssaidi@eecs.umich.edu               ULL(0x20) << 24 |
2484207Ssaidi@eecs.umich.edu                   //MaxGL << 16 | XXX For some reason legion doesn't set GL
2494207Ssaidi@eecs.umich.edu                   MaxTL << 8  |
2504207Ssaidi@eecs.umich.edu           (NWindows -1) << 0;
2512650Ssaidi@eecs.umich.edu
2524194Ssaidi@eecs.umich.edu      case MISCREG_STRAND_STS_REG:
2534194Ssaidi@eecs.umich.edu        System *sys;
2544194Ssaidi@eecs.umich.edu        int x;
2554194Ssaidi@eecs.umich.edu        sys = tc->getSystemPtr();
2564194Ssaidi@eecs.umich.edu
2574194Ssaidi@eecs.umich.edu        temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
2585531Snate@binkert.org        // Check that the CPU array is fully populated
2595531Snate@binkert.org        // (by calling getNumCPus())
2604194Ssaidi@eecs.umich.edu        assert(sys->getNumCPUs() > tc->readCpuId());
2614194Ssaidi@eecs.umich.edu
2624194Ssaidi@eecs.umich.edu        temp |= tc->readCpuId()  << STS::shft_id;
2634194Ssaidi@eecs.umich.edu
2644194Ssaidi@eecs.umich.edu        for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
2654194Ssaidi@eecs.umich.edu            switch (sys->threadContexts[x]->status()) {
2664194Ssaidi@eecs.umich.edu              case ThreadContext::Active:
2674194Ssaidi@eecs.umich.edu                temp |= STS::st_run << (STS::shft_fsm0 -
2684194Ssaidi@eecs.umich.edu                        ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
2694194Ssaidi@eecs.umich.edu                break;
2704194Ssaidi@eecs.umich.edu              case ThreadContext::Suspended:
2714194Ssaidi@eecs.umich.edu                // should this be idle?
2724194Ssaidi@eecs.umich.edu                temp |= STS::st_idle << (STS::shft_fsm0 -
2734194Ssaidi@eecs.umich.edu                        ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
2744194Ssaidi@eecs.umich.edu                break;
2754194Ssaidi@eecs.umich.edu              case ThreadContext::Halted:
2764194Ssaidi@eecs.umich.edu                temp |= STS::st_halt << (STS::shft_fsm0 -
2774194Ssaidi@eecs.umich.edu                        ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
2784194Ssaidi@eecs.umich.edu                break;
2794194Ssaidi@eecs.umich.edu              default:
2804194Ssaidi@eecs.umich.edu                panic("What state are we in?!\n");
2814194Ssaidi@eecs.umich.edu            } // switch
2824194Ssaidi@eecs.umich.edu        } // for
2834194Ssaidi@eecs.umich.edu
2844194Ssaidi@eecs.umich.edu        return temp;
2853825Ssaidi@eecs.umich.edu      default:
2863825Ssaidi@eecs.umich.edu        panic("Invalid read to FS misc register\n");
2872650Ssaidi@eecs.umich.edu    }
2882650Ssaidi@eecs.umich.edu}
2892650Ssaidi@eecs.umich.edu
2902651Ssaidi@eecs.umich.eduvoid
2912680Sktlim@umich.eduMiscRegFile::processTickCompare(ThreadContext *tc)
2922651Ssaidi@eecs.umich.edu{
2932651Ssaidi@eecs.umich.edu    panic("tick compare not implemented\n");
2942651Ssaidi@eecs.umich.edu}
2952651Ssaidi@eecs.umich.edu
2962651Ssaidi@eecs.umich.eduvoid
2972680Sktlim@umich.eduMiscRegFile::processSTickCompare(ThreadContext *tc)
2982651Ssaidi@eecs.umich.edu{
2993888Ssaidi@eecs.umich.edu    // since our microcode instructions take two cycles we need to check if
3003888Ssaidi@eecs.umich.edu    // we're actually at the correct cycle or we need to wait a little while
3013888Ssaidi@eecs.umich.edu    // more
3023888Ssaidi@eecs.umich.edu    int ticks;
3033890Ssaidi@eecs.umich.edu    ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
3043919Shsul@eecs.umich.edu        tc->getCpuPtr()->instCount();
3053888Ssaidi@eecs.umich.edu    assert(ticks >= 0 && "stick compare missed interrupt cycle");
3063888Ssaidi@eecs.umich.edu
3074216Ssaidi@eecs.umich.edu    if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
3083888Ssaidi@eecs.umich.edu        DPRINTF(Timer, "STick compare cycle reached at %#x\n",
3093888Ssaidi@eecs.umich.edu                (stick_cmpr & mask(63)));
3104172Ssaidi@eecs.umich.edu        if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
3114172Ssaidi@eecs.umich.edu            setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
3123921Shsul@eecs.umich.edu        }
3133888Ssaidi@eecs.umich.edu    } else
3145100Ssaidi@eecs.umich.edu        sTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
3152651Ssaidi@eecs.umich.edu}
3162651Ssaidi@eecs.umich.edu
3172651Ssaidi@eecs.umich.eduvoid
3182680Sktlim@umich.eduMiscRegFile::processHSTickCompare(ThreadContext *tc)
3192651Ssaidi@eecs.umich.edu{
3203891Ssaidi@eecs.umich.edu    // since our microcode instructions take two cycles we need to check if
3213891Ssaidi@eecs.umich.edu    // we're actually at the correct cycle or we need to wait a little while
3223891Ssaidi@eecs.umich.edu    // more
3233891Ssaidi@eecs.umich.edu    int ticks;
3244216Ssaidi@eecs.umich.edu    if ( tc->status() == ThreadContext::Halted ||
3254216Ssaidi@eecs.umich.edu         tc->status() == ThreadContext::Unallocated)
3264216Ssaidi@eecs.umich.edu       return;
3274216Ssaidi@eecs.umich.edu
3283891Ssaidi@eecs.umich.edu    ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
3293919Shsul@eecs.umich.edu        tc->getCpuPtr()->instCount();
3303891Ssaidi@eecs.umich.edu    assert(ticks >= 0 && "hstick compare missed interrupt cycle");
3313891Ssaidi@eecs.umich.edu
3324216Ssaidi@eecs.umich.edu    if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
3333891Ssaidi@eecs.umich.edu        DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
3343891Ssaidi@eecs.umich.edu                (stick_cmpr & mask(63)));
3354172Ssaidi@eecs.umich.edu        if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
3364172Ssaidi@eecs.umich.edu            setReg(MISCREG_HINTP, 1, tc);
3373921Shsul@eecs.umich.edu        }
3383891Ssaidi@eecs.umich.edu        // Need to do something to cause interrupt to happen here !!! @todo
3393891Ssaidi@eecs.umich.edu    } else
3405100Ssaidi@eecs.umich.edu        hSTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
3412651Ssaidi@eecs.umich.edu}
3422650Ssaidi@eecs.umich.edu
343