ua2005.cc revision 3897
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 293817Ssaidi@eecs.umich.edu#include "arch/sparc/miscregfile.hh" 303817Ssaidi@eecs.umich.edu#include "base/bitfield.hh" 313817Ssaidi@eecs.umich.edu#include "base/trace.hh" 323817Ssaidi@eecs.umich.edu#include "cpu/base.hh" 333817Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh" 342650Ssaidi@eecs.umich.edu 353817Ssaidi@eecs.umich.eduusing namespace SparcISA; 363817Ssaidi@eecs.umich.edu 373817Ssaidi@eecs.umich.eduvoid 383817Ssaidi@eecs.umich.eduMiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, 393894Shsul@eecs.umich.edu ThreadContext *tc) 402650Ssaidi@eecs.umich.edu{ 412650Ssaidi@eecs.umich.edu int64_t time; 422650Ssaidi@eecs.umich.edu switch (miscReg) { 432982Sstever@eecs.umich.edu /* Full system only ASRs */ 443894Shsul@eecs.umich.edu case MISCREG_SOFTINT: 453894Shsul@eecs.umich.edu // Check if we are going to interrupt because of something 463894Shsul@eecs.umich.edu setReg(miscReg, val); 473894Shsul@eecs.umich.edu tc->getCpuPtr()->post_interrupt(soft_interrupt); 483894Shsul@eecs.umich.edu warn("Writing to softint not really supported, writing: %#x\n", val); 493894Shsul@eecs.umich.edu break; 502650Ssaidi@eecs.umich.edu 513894Shsul@eecs.umich.edu case MISCREG_SOFTINT_CLR: 523894Shsul@eecs.umich.edu return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); 533894Shsul@eecs.umich.edu case MISCREG_SOFTINT_SET: 543894Shsul@eecs.umich.edu return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); 552650Ssaidi@eecs.umich.edu 563894Shsul@eecs.umich.edu case MISCREG_TICK_CMPR: 573894Shsul@eecs.umich.edu if (tickCompare == NULL) 583894Shsul@eecs.umich.edu tickCompare = new TickCompareEvent(this, tc); 593894Shsul@eecs.umich.edu setReg(miscReg, val); 603894Shsul@eecs.umich.edu if ((tick_cmpr & mask(63)) && tickCompare->scheduled()) 613894Shsul@eecs.umich.edu tickCompare->deschedule(); 623894Shsul@eecs.umich.edu time = (tick_cmpr & mask(63)) - (tick & mask(63)); 633894Shsul@eecs.umich.edu if (!(tick_cmpr & ~mask(63)) && time > 0) 643894Shsul@eecs.umich.edu tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); 653894Shsul@eecs.umich.edu panic("writing to TICK compare register %#X\n", val); 663894Shsul@eecs.umich.edu break; 672650Ssaidi@eecs.umich.edu 683894Shsul@eecs.umich.edu case MISCREG_STICK_CMPR: 693894Shsul@eecs.umich.edu if (sTickCompare == NULL) 703894Shsul@eecs.umich.edu sTickCompare = new STickCompareEvent(this, tc); 713894Shsul@eecs.umich.edu setReg(miscReg, val); 723894Shsul@eecs.umich.edu if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) 733894Shsul@eecs.umich.edu sTickCompare->deschedule(); 743894Shsul@eecs.umich.edu time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 753894Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 763894Shsul@eecs.umich.edu if (!(stick_cmpr & ~mask(63)) && time > 0) 773894Shsul@eecs.umich.edu sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); 783894Shsul@eecs.umich.edu DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); 793894Shsul@eecs.umich.edu break; 802650Ssaidi@eecs.umich.edu 813894Shsul@eecs.umich.edu case MISCREG_PSTATE: 823897Shsul@eecs.umich.edu if (val & PSTATE::ie && !(pstate & PSTATE::ie)) { 833894Shsul@eecs.umich.edu tc->getCpuPtr()->checkInterrupts = true; 843894Shsul@eecs.umich.edu } 853894Shsul@eecs.umich.edu setReg(miscReg, val); 863827Shsul@eecs.umich.edu 873894Shsul@eecs.umich.edu case MISCREG_PIL: 883894Shsul@eecs.umich.edu if (val < pil) { 893894Shsul@eecs.umich.edu tc->getCpuPtr()->checkInterrupts = true; 903894Shsul@eecs.umich.edu } 913894Shsul@eecs.umich.edu setReg(miscReg, val); 923894Shsul@eecs.umich.edu break; 932650Ssaidi@eecs.umich.edu 943894Shsul@eecs.umich.edu case MISCREG_HVER: 953894Shsul@eecs.umich.edu panic("Shouldn't be writing HVER\n"); 962650Ssaidi@eecs.umich.edu 973894Shsul@eecs.umich.edu case MISCREG_HTBA: 983894Shsul@eecs.umich.edu // clear lower 7 bits on writes. 993894Shsul@eecs.umich.edu setReg(miscReg, val & ULL(~0x7FFF)); 1003894Shsul@eecs.umich.edu break; 1012650Ssaidi@eecs.umich.edu 1023894Shsul@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_HEAD: 1033894Shsul@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_TAIL: 1043894Shsul@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_HEAD: 1053894Shsul@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_TAIL: 1063894Shsul@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_HEAD: 1073894Shsul@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_TAIL: 1083894Shsul@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_HEAD: 1093894Shsul@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_TAIL: 1103894Shsul@eecs.umich.edu setReg(miscReg, val); 1113894Shsul@eecs.umich.edu tc->getCpuPtr()->checkInterrupts = true; 1123894Shsul@eecs.umich.edu break; 1133828Shsul@eecs.umich.edu 1143894Shsul@eecs.umich.edu case MISCREG_HSTICK_CMPR: 1153894Shsul@eecs.umich.edu if (hSTickCompare == NULL) 1163894Shsul@eecs.umich.edu hSTickCompare = new HSTickCompareEvent(this, tc); 1173894Shsul@eecs.umich.edu setReg(miscReg, val); 1183894Shsul@eecs.umich.edu if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) 1193894Shsul@eecs.umich.edu hSTickCompare->deschedule(); 1203894Shsul@eecs.umich.edu time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 1213894Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 1223894Shsul@eecs.umich.edu if (!(hstick_cmpr & ~mask(63)) && time > 0) 1233894Shsul@eecs.umich.edu hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); 1243894Shsul@eecs.umich.edu DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); 1253894Shsul@eecs.umich.edu break; 1263817Ssaidi@eecs.umich.edu 1273894Shsul@eecs.umich.edu case MISCREG_HPSTATE: 1283894Shsul@eecs.umich.edu // T1000 spec says impl. dependent val must always be 1 1293897Shsul@eecs.umich.edu setReg(miscReg, val | HPSTATE::id); 1303894Shsul@eecs.umich.edu break; 1313894Shsul@eecs.umich.edu case MISCREG_HTSTATE: 1323894Shsul@eecs.umich.edu case MISCREG_STRAND_STS_REG: 1333894Shsul@eecs.umich.edu setReg(miscReg, val); 1343894Shsul@eecs.umich.edu break; 1353817Ssaidi@eecs.umich.edu 1363894Shsul@eecs.umich.edu default: 1373894Shsul@eecs.umich.edu panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); 1382650Ssaidi@eecs.umich.edu } 1392650Ssaidi@eecs.umich.edu} 1402650Ssaidi@eecs.umich.edu 1412650Ssaidi@eecs.umich.eduMiscReg 1423817Ssaidi@eecs.umich.eduMiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) 1432650Ssaidi@eecs.umich.edu{ 1442650Ssaidi@eecs.umich.edu switch (miscReg) { 1453894Shsul@eecs.umich.edu /* Privileged registers. */ 1463825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_HEAD: 1473825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_TAIL: 1483825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_HEAD: 1493825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_TAIL: 1503825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_HEAD: 1513825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_TAIL: 1523825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_HEAD: 1533825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_TAIL: 1543825Ssaidi@eecs.umich.edu case MISCREG_SOFTINT: 1553825Ssaidi@eecs.umich.edu case MISCREG_TICK_CMPR: 1563825Ssaidi@eecs.umich.edu case MISCREG_STICK_CMPR: 1573825Ssaidi@eecs.umich.edu case MISCREG_PIL: 1583825Ssaidi@eecs.umich.edu case MISCREG_HPSTATE: 1593825Ssaidi@eecs.umich.edu case MISCREG_HINTP: 1603825Ssaidi@eecs.umich.edu case MISCREG_HTSTATE: 1613825Ssaidi@eecs.umich.edu case MISCREG_STRAND_STS_REG: 1623825Ssaidi@eecs.umich.edu case MISCREG_HSTICK_CMPR: 1633825Ssaidi@eecs.umich.edu return readReg(miscReg) ; 1642650Ssaidi@eecs.umich.edu 1653825Ssaidi@eecs.umich.edu case MISCREG_HTBA: 1663825Ssaidi@eecs.umich.edu return readReg(miscReg) & ULL(~0x7FFF); 1673825Ssaidi@eecs.umich.edu case MISCREG_HVER: 1683825Ssaidi@eecs.umich.edu return NWindows | MaxTL << 8 | MaxGL << 16; 1692650Ssaidi@eecs.umich.edu 1703825Ssaidi@eecs.umich.edu default: 1713825Ssaidi@eecs.umich.edu panic("Invalid read to FS misc register\n"); 1722650Ssaidi@eecs.umich.edu } 1732650Ssaidi@eecs.umich.edu} 1743817Ssaidi@eecs.umich.edu/* 1753894Shsul@eecs.umich.edu In Niagra STICK==TICK so this isn't needed 1763894Shsul@eecs.umich.edu case MISCREG_STICK: 1773894Shsul@eecs.umich.edu SparcSystem *sys; 1783894Shsul@eecs.umich.edu sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); 1793894Shsul@eecs.umich.edu assert(sys != NULL); 1803894Shsul@eecs.umich.edu return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); 1813817Ssaidi@eecs.umich.edu*/ 1823817Ssaidi@eecs.umich.edu 1833817Ssaidi@eecs.umich.edu 1842650Ssaidi@eecs.umich.edu 1852651Ssaidi@eecs.umich.eduvoid 1862680Sktlim@umich.eduMiscRegFile::processTickCompare(ThreadContext *tc) 1872651Ssaidi@eecs.umich.edu{ 1882651Ssaidi@eecs.umich.edu panic("tick compare not implemented\n"); 1892651Ssaidi@eecs.umich.edu} 1902651Ssaidi@eecs.umich.edu 1912651Ssaidi@eecs.umich.eduvoid 1922680Sktlim@umich.eduMiscRegFile::processSTickCompare(ThreadContext *tc) 1932651Ssaidi@eecs.umich.edu{ 1943888Ssaidi@eecs.umich.edu // since our microcode instructions take two cycles we need to check if 1953888Ssaidi@eecs.umich.edu // we're actually at the correct cycle or we need to wait a little while 1963888Ssaidi@eecs.umich.edu // more 1973888Ssaidi@eecs.umich.edu int ticks; 1983890Ssaidi@eecs.umich.edu ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 1993894Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 2003888Ssaidi@eecs.umich.edu assert(ticks >= 0 && "stick compare missed interrupt cycle"); 2013888Ssaidi@eecs.umich.edu 2023888Ssaidi@eecs.umich.edu if (ticks == 0) { 2033888Ssaidi@eecs.umich.edu DPRINTF(Timer, "STick compare cycle reached at %#x\n", 2043888Ssaidi@eecs.umich.edu (stick_cmpr & mask(63))); 2053894Shsul@eecs.umich.edu tc->getCpuPtr()->post_interrupt(soft_interrupt); 2063888Ssaidi@eecs.umich.edu tc->getCpuPtr()->checkInterrupts = true; 2073890Ssaidi@eecs.umich.edu softint |= ULL(1) << 16; 2083888Ssaidi@eecs.umich.edu } else 2093888Ssaidi@eecs.umich.edu sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 2102651Ssaidi@eecs.umich.edu} 2112651Ssaidi@eecs.umich.edu 2122651Ssaidi@eecs.umich.eduvoid 2132680Sktlim@umich.eduMiscRegFile::processHSTickCompare(ThreadContext *tc) 2142651Ssaidi@eecs.umich.edu{ 2153891Ssaidi@eecs.umich.edu // since our microcode instructions take two cycles we need to check if 2163891Ssaidi@eecs.umich.edu // we're actually at the correct cycle or we need to wait a little while 2173891Ssaidi@eecs.umich.edu // more 2183891Ssaidi@eecs.umich.edu int ticks; 2193891Ssaidi@eecs.umich.edu ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 2203894Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 2213891Ssaidi@eecs.umich.edu assert(ticks >= 0 && "hstick compare missed interrupt cycle"); 2223891Ssaidi@eecs.umich.edu 2233891Ssaidi@eecs.umich.edu if (ticks == 0) { 2243891Ssaidi@eecs.umich.edu DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", 2253891Ssaidi@eecs.umich.edu (stick_cmpr & mask(63))); 2263894Shsul@eecs.umich.edu tc->getCpuPtr()->post_interrupt(hstick_match); 2273891Ssaidi@eecs.umich.edu tc->getCpuPtr()->checkInterrupts = true; 2283891Ssaidi@eecs.umich.edu // Need to do something to cause interrupt to happen here !!! @todo 2293891Ssaidi@eecs.umich.edu } else 2303891Ssaidi@eecs.umich.edu sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 2312651Ssaidi@eecs.umich.edu} 2322650Ssaidi@eecs.umich.edu 233