ua2005.cc revision 4103
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 374103Ssaidi@eecs.umich.edu 384103Ssaidi@eecs.umich.eduvoid 394103Ssaidi@eecs.umich.eduMiscRegFile::checkSoftInt(ThreadContext *tc) 404103Ssaidi@eecs.umich.edu{ 414103Ssaidi@eecs.umich.edu // If PIL < 14, copy over the tm and sm bits 424103Ssaidi@eecs.umich.edu if (pil < 14 && softint & 0x10000) 434103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16); 444103Ssaidi@eecs.umich.edu else 454103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16); 464103Ssaidi@eecs.umich.edu if (pil < 14 && softint & 0x1) 474103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0); 484103Ssaidi@eecs.umich.edu else 494103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0); 504103Ssaidi@eecs.umich.edu 514103Ssaidi@eecs.umich.edu // Copy over any of the other bits that are set 524103Ssaidi@eecs.umich.edu for (int bit = 15; bit > 0; --bit) { 534103Ssaidi@eecs.umich.edu if (1 << bit & softint && bit > pil) 544103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit); 554103Ssaidi@eecs.umich.edu else 564103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit); 574103Ssaidi@eecs.umich.edu } 584103Ssaidi@eecs.umich.edu} 594103Ssaidi@eecs.umich.edu 604103Ssaidi@eecs.umich.edu 613817Ssaidi@eecs.umich.eduvoid 623817Ssaidi@eecs.umich.eduMiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, 633919Shsul@eecs.umich.edu ThreadContext *tc) 642650Ssaidi@eecs.umich.edu{ 652650Ssaidi@eecs.umich.edu int64_t time; 662650Ssaidi@eecs.umich.edu switch (miscReg) { 672982Sstever@eecs.umich.edu /* Full system only ASRs */ 683919Shsul@eecs.umich.edu case MISCREG_SOFTINT: 693921Shsul@eecs.umich.edu setReg(miscReg, val);; 704103Ssaidi@eecs.umich.edu checkSoftInt(tc); 713919Shsul@eecs.umich.edu break; 723919Shsul@eecs.umich.edu case MISCREG_SOFTINT_CLR: 733919Shsul@eecs.umich.edu return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); 743919Shsul@eecs.umich.edu case MISCREG_SOFTINT_SET: 753919Shsul@eecs.umich.edu return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); 762650Ssaidi@eecs.umich.edu 773919Shsul@eecs.umich.edu case MISCREG_TICK_CMPR: 783919Shsul@eecs.umich.edu if (tickCompare == NULL) 793919Shsul@eecs.umich.edu tickCompare = new TickCompareEvent(this, tc); 803919Shsul@eecs.umich.edu setReg(miscReg, val); 814103Ssaidi@eecs.umich.edu if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled()) 823919Shsul@eecs.umich.edu tickCompare->deschedule(); 833919Shsul@eecs.umich.edu time = (tick_cmpr & mask(63)) - (tick & mask(63)); 844103Ssaidi@eecs.umich.edu if (!(tick_cmpr & ~mask(63)) && time > 0) { 854103Ssaidi@eecs.umich.edu if (tickCompare->scheduled()) 864103Ssaidi@eecs.umich.edu tickCompare->deschedule(); 873919Shsul@eecs.umich.edu tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); 884103Ssaidi@eecs.umich.edu } 893919Shsul@eecs.umich.edu panic("writing to TICK compare register %#X\n", val); 903919Shsul@eecs.umich.edu break; 912650Ssaidi@eecs.umich.edu 923919Shsul@eecs.umich.edu case MISCREG_STICK_CMPR: 933919Shsul@eecs.umich.edu if (sTickCompare == NULL) 943919Shsul@eecs.umich.edu sTickCompare = new STickCompareEvent(this, tc); 953919Shsul@eecs.umich.edu setReg(miscReg, val); 963919Shsul@eecs.umich.edu if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) 973919Shsul@eecs.umich.edu sTickCompare->deschedule(); 983919Shsul@eecs.umich.edu time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 993919Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 1004103Ssaidi@eecs.umich.edu if (!(stick_cmpr & ~mask(63)) && time > 0) { 1014103Ssaidi@eecs.umich.edu if (sTickCompare->scheduled()) 1024103Ssaidi@eecs.umich.edu sTickCompare->deschedule(); 1033919Shsul@eecs.umich.edu sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); 1044103Ssaidi@eecs.umich.edu } 1053919Shsul@eecs.umich.edu DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); 1063919Shsul@eecs.umich.edu break; 1072650Ssaidi@eecs.umich.edu 1083919Shsul@eecs.umich.edu case MISCREG_PSTATE: 1093919Shsul@eecs.umich.edu setReg(miscReg, val); 1103827Shsul@eecs.umich.edu 1113919Shsul@eecs.umich.edu case MISCREG_PIL: 1123919Shsul@eecs.umich.edu setReg(miscReg, val); 1134103Ssaidi@eecs.umich.edu checkSoftInt(tc); 1143919Shsul@eecs.umich.edu break; 1152650Ssaidi@eecs.umich.edu 1163919Shsul@eecs.umich.edu case MISCREG_HVER: 1173919Shsul@eecs.umich.edu panic("Shouldn't be writing HVER\n"); 1182650Ssaidi@eecs.umich.edu 1193921Shsul@eecs.umich.edu case MISCREG_HINTP: 1203921Shsul@eecs.umich.edu setReg(miscReg, val); 1214103Ssaidi@eecs.umich.edu if (hintp) 1224103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_HINTP,0); 1234103Ssaidi@eecs.umich.edu else 1244103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_HINTP,0); 1254103Ssaidi@eecs.umich.edu break; 1263921Shsul@eecs.umich.edu 1273919Shsul@eecs.umich.edu case MISCREG_HTBA: 1283919Shsul@eecs.umich.edu // clear lower 7 bits on writes. 1293919Shsul@eecs.umich.edu setReg(miscReg, val & ULL(~0x7FFF)); 1303919Shsul@eecs.umich.edu break; 1312650Ssaidi@eecs.umich.edu 1323919Shsul@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_HEAD: 1333919Shsul@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_TAIL: 1344103Ssaidi@eecs.umich.edu setReg(miscReg, val); 1354103Ssaidi@eecs.umich.edu if (cpu_mondo_head != cpu_mondo_tail) 1364103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0); 1374103Ssaidi@eecs.umich.edu else 1384103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0); 1394103Ssaidi@eecs.umich.edu break; 1403919Shsul@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_HEAD: 1413919Shsul@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_TAIL: 1424103Ssaidi@eecs.umich.edu setReg(miscReg, val); 1434103Ssaidi@eecs.umich.edu if (dev_mondo_head != dev_mondo_tail) 1444103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0); 1454103Ssaidi@eecs.umich.edu else 1464103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0); 1474103Ssaidi@eecs.umich.edu break; 1483919Shsul@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_HEAD: 1493919Shsul@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_TAIL: 1504103Ssaidi@eecs.umich.edu setReg(miscReg, val); 1514103Ssaidi@eecs.umich.edu if (res_error_head != res_error_tail) 1524103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0); 1534103Ssaidi@eecs.umich.edu else 1544103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0); 1554103Ssaidi@eecs.umich.edu break; 1563919Shsul@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_HEAD: 1573919Shsul@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_TAIL: 1583919Shsul@eecs.umich.edu setReg(miscReg, val); 1594103Ssaidi@eecs.umich.edu // This one doesn't have an interrupt to report to the guest OS 1603919Shsul@eecs.umich.edu break; 1613828Shsul@eecs.umich.edu 1623919Shsul@eecs.umich.edu case MISCREG_HSTICK_CMPR: 1633919Shsul@eecs.umich.edu if (hSTickCompare == NULL) 1643919Shsul@eecs.umich.edu hSTickCompare = new HSTickCompareEvent(this, tc); 1653919Shsul@eecs.umich.edu setReg(miscReg, val); 1663919Shsul@eecs.umich.edu if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) 1673919Shsul@eecs.umich.edu hSTickCompare->deschedule(); 1683919Shsul@eecs.umich.edu time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 1693919Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 1704103Ssaidi@eecs.umich.edu if (!(hstick_cmpr & ~mask(63)) && time > 0) { 1714103Ssaidi@eecs.umich.edu if (hSTickCompare->scheduled()) 1724103Ssaidi@eecs.umich.edu hSTickCompare->deschedule(); 1733919Shsul@eecs.umich.edu hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); 1744103Ssaidi@eecs.umich.edu } 1753919Shsul@eecs.umich.edu DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); 1763919Shsul@eecs.umich.edu break; 1773817Ssaidi@eecs.umich.edu 1783919Shsul@eecs.umich.edu case MISCREG_HPSTATE: 1793919Shsul@eecs.umich.edu // T1000 spec says impl. dependent val must always be 1 1803897Shsul@eecs.umich.edu setReg(miscReg, val | HPSTATE::id); 1814103Ssaidi@eecs.umich.edu#if FULL_SYSTEM 1824103Ssaidi@eecs.umich.edu if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) 1834103Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0); 1844103Ssaidi@eecs.umich.edu else 1854103Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0); 1864103Ssaidi@eecs.umich.edu#endif 1873919Shsul@eecs.umich.edu break; 1883919Shsul@eecs.umich.edu case MISCREG_HTSTATE: 1893919Shsul@eecs.umich.edu case MISCREG_STRAND_STS_REG: 1903919Shsul@eecs.umich.edu setReg(miscReg, val); 1913919Shsul@eecs.umich.edu break; 1923817Ssaidi@eecs.umich.edu 1933919Shsul@eecs.umich.edu default: 1943919Shsul@eecs.umich.edu panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); 1952650Ssaidi@eecs.umich.edu } 1962650Ssaidi@eecs.umich.edu} 1972650Ssaidi@eecs.umich.edu 1982650Ssaidi@eecs.umich.eduMiscReg 1993817Ssaidi@eecs.umich.eduMiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) 2002650Ssaidi@eecs.umich.edu{ 2012650Ssaidi@eecs.umich.edu switch (miscReg) { 2023919Shsul@eecs.umich.edu /* Privileged registers. */ 2033825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_HEAD: 2043825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_TAIL: 2053825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_HEAD: 2063825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_TAIL: 2073825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_HEAD: 2083825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_TAIL: 2093825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_HEAD: 2103825Ssaidi@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_TAIL: 2113825Ssaidi@eecs.umich.edu case MISCREG_SOFTINT: 2123825Ssaidi@eecs.umich.edu case MISCREG_TICK_CMPR: 2133825Ssaidi@eecs.umich.edu case MISCREG_STICK_CMPR: 2143825Ssaidi@eecs.umich.edu case MISCREG_PIL: 2153825Ssaidi@eecs.umich.edu case MISCREG_HPSTATE: 2163825Ssaidi@eecs.umich.edu case MISCREG_HINTP: 2173825Ssaidi@eecs.umich.edu case MISCREG_HTSTATE: 2183825Ssaidi@eecs.umich.edu case MISCREG_STRAND_STS_REG: 2193825Ssaidi@eecs.umich.edu case MISCREG_HSTICK_CMPR: 2203825Ssaidi@eecs.umich.edu return readReg(miscReg) ; 2212650Ssaidi@eecs.umich.edu 2223825Ssaidi@eecs.umich.edu case MISCREG_HTBA: 2233825Ssaidi@eecs.umich.edu return readReg(miscReg) & ULL(~0x7FFF); 2243825Ssaidi@eecs.umich.edu case MISCREG_HVER: 2253825Ssaidi@eecs.umich.edu return NWindows | MaxTL << 8 | MaxGL << 16; 2262650Ssaidi@eecs.umich.edu 2273825Ssaidi@eecs.umich.edu default: 2283825Ssaidi@eecs.umich.edu panic("Invalid read to FS misc register\n"); 2292650Ssaidi@eecs.umich.edu } 2302650Ssaidi@eecs.umich.edu} 2313817Ssaidi@eecs.umich.edu/* 2323919Shsul@eecs.umich.edu In Niagra STICK==TICK so this isn't needed 2333919Shsul@eecs.umich.edu case MISCREG_STICK: 2343919Shsul@eecs.umich.edu SparcSystem *sys; 2353919Shsul@eecs.umich.edu sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); 2363919Shsul@eecs.umich.edu assert(sys != NULL); 2373919Shsul@eecs.umich.edu return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); 2383817Ssaidi@eecs.umich.edu*/ 2393817Ssaidi@eecs.umich.edu 2403817Ssaidi@eecs.umich.edu 2412650Ssaidi@eecs.umich.edu 2422651Ssaidi@eecs.umich.eduvoid 2432680Sktlim@umich.eduMiscRegFile::processTickCompare(ThreadContext *tc) 2442651Ssaidi@eecs.umich.edu{ 2452651Ssaidi@eecs.umich.edu panic("tick compare not implemented\n"); 2462651Ssaidi@eecs.umich.edu} 2472651Ssaidi@eecs.umich.edu 2482651Ssaidi@eecs.umich.eduvoid 2492680Sktlim@umich.eduMiscRegFile::processSTickCompare(ThreadContext *tc) 2502651Ssaidi@eecs.umich.edu{ 2513888Ssaidi@eecs.umich.edu // since our microcode instructions take two cycles we need to check if 2523888Ssaidi@eecs.umich.edu // we're actually at the correct cycle or we need to wait a little while 2533888Ssaidi@eecs.umich.edu // more 2543888Ssaidi@eecs.umich.edu int ticks; 2553890Ssaidi@eecs.umich.edu ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 2563919Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 2573888Ssaidi@eecs.umich.edu assert(ticks >= 0 && "stick compare missed interrupt cycle"); 2583888Ssaidi@eecs.umich.edu 2593888Ssaidi@eecs.umich.edu if (ticks == 0) { 2603888Ssaidi@eecs.umich.edu DPRINTF(Timer, "STick compare cycle reached at %#x\n", 2613888Ssaidi@eecs.umich.edu (stick_cmpr & mask(63))); 2623921Shsul@eecs.umich.edu if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) { 2633921Shsul@eecs.umich.edu setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); 2643921Shsul@eecs.umich.edu } 2653888Ssaidi@eecs.umich.edu } else 2663888Ssaidi@eecs.umich.edu sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 2672651Ssaidi@eecs.umich.edu} 2682651Ssaidi@eecs.umich.edu 2692651Ssaidi@eecs.umich.eduvoid 2702680Sktlim@umich.eduMiscRegFile::processHSTickCompare(ThreadContext *tc) 2712651Ssaidi@eecs.umich.edu{ 2723891Ssaidi@eecs.umich.edu // since our microcode instructions take two cycles we need to check if 2733891Ssaidi@eecs.umich.edu // we're actually at the correct cycle or we need to wait a little while 2743891Ssaidi@eecs.umich.edu // more 2753891Ssaidi@eecs.umich.edu int ticks; 2763891Ssaidi@eecs.umich.edu ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 2773919Shsul@eecs.umich.edu tc->getCpuPtr()->instCount(); 2783891Ssaidi@eecs.umich.edu assert(ticks >= 0 && "hstick compare missed interrupt cycle"); 2793891Ssaidi@eecs.umich.edu 2803891Ssaidi@eecs.umich.edu if (ticks == 0) { 2813891Ssaidi@eecs.umich.edu DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", 2823891Ssaidi@eecs.umich.edu (stick_cmpr & mask(63))); 2833921Shsul@eecs.umich.edu if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) { 2843921Shsul@eecs.umich.edu setRegWithEffect(MISCREG_HINTP, 1, tc); 2853921Shsul@eecs.umich.edu } 2863891Ssaidi@eecs.umich.edu // Need to do something to cause interrupt to happen here !!! @todo 2873891Ssaidi@eecs.umich.edu } else 2884103Ssaidi@eecs.umich.edu hSTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 2892651Ssaidi@eecs.umich.edu} 2902650Ssaidi@eecs.umich.edu 291