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