ua2005.cc revision 4103
12623SN/A/* 22623SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32623SN/A * All rights reserved. 42623SN/A * 52623SN/A * Redistribution and use in source and binary forms, with or without 62623SN/A * modification, are permitted provided that the following conditions are 72623SN/A * met: redistributions of source code must retain the above copyright 82623SN/A * notice, this list of conditions and the following disclaimer; 92623SN/A * redistributions in binary form must reproduce the above copyright 102623SN/A * notice, this list of conditions and the following disclaimer in the 112623SN/A * documentation and/or other materials provided with the distribution; 122623SN/A * neither the name of the copyright holders nor the names of its 132623SN/A * contributors may be used to endorse or promote products derived from 142623SN/A * this software without specific prior written permission. 152623SN/A * 162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292623SN/A#include "arch/sparc/miscregfile.hh" 302623SN/A#include "base/bitfield.hh" 312623SN/A#include "base/trace.hh" 322623SN/A#include "cpu/base.hh" 332623SN/A#include "cpu/thread_context.hh" 342623SN/A 352623SN/Ausing namespace SparcISA; 362623SN/A 372623SN/A 382623SN/Avoid 392623SN/AMiscRegFile::checkSoftInt(ThreadContext *tc) 402623SN/A{ 412623SN/A // If PIL < 14, copy over the tm and sm bits 422623SN/A if (pil < 14 && softint & 0x10000) 432623SN/A tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16); 442623SN/A else 452623SN/A tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16); 462623SN/A if (pil < 14 && softint & 0x1) 472623SN/A tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0); 482623SN/A else 492623SN/A tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0); 502623SN/A 512623SN/A // Copy over any of the other bits that are set 522623SN/A for (int bit = 15; bit > 0; --bit) { 532623SN/A if (1 << bit & softint && bit > pil) 542623SN/A tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit); 552623SN/A else 562623SN/A tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit); 572623SN/A } 582623SN/A} 592623SN/A 602623SN/A 612623SN/Avoid 622623SN/AMiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, 632623SN/A ThreadContext *tc) 642623SN/A{ 652623SN/A int64_t time; 662623SN/A switch (miscReg) { 672839Sktlim@umich.edu /* Full system only ASRs */ 682798Sktlim@umich.edu case MISCREG_SOFTINT: 692867Sktlim@umich.edu setReg(miscReg, val);; 702867Sktlim@umich.edu checkSoftInt(tc); 712623SN/A break; 722623SN/A case MISCREG_SOFTINT_CLR: 732623SN/A return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); 742623SN/A case MISCREG_SOFTINT_SET: 752623SN/A return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); 762623SN/A 772948Ssaidi@eecs.umich.edu case MISCREG_TICK_CMPR: 782623SN/A if (tickCompare == NULL) 792623SN/A tickCompare = new TickCompareEvent(this, tc); 802623SN/A setReg(miscReg, val); 812948Ssaidi@eecs.umich.edu if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled()) 823401Sktlim@umich.edu tickCompare->deschedule(); 832623SN/A time = (tick_cmpr & mask(63)) - (tick & mask(63)); 842623SN/A if (!(tick_cmpr & ~mask(63)) && time > 0) { 852623SN/A if (tickCompare->scheduled()) 862623SN/A tickCompare->deschedule(); 873349Sbinkertn@umich.edu tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); 882623SN/A } 893349Sbinkertn@umich.edu panic("writing to TICK compare register %#X\n", val); 902623SN/A break; 912623SN/A 922623SN/A case MISCREG_STICK_CMPR: 932623SN/A if (sTickCompare == NULL) 942623SN/A sTickCompare = new STickCompareEvent(this, tc); 953192Srdreslin@umich.edu setReg(miscReg, val); 962948Ssaidi@eecs.umich.edu if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) 972948Ssaidi@eecs.umich.edu sTickCompare->deschedule(); 982948Ssaidi@eecs.umich.edu time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 993349Sbinkertn@umich.edu tc->getCpuPtr()->instCount(); 1002948Ssaidi@eecs.umich.edu if (!(stick_cmpr & ~mask(63)) && time > 0) { 1012948Ssaidi@eecs.umich.edu if (sTickCompare->scheduled()) 1022948Ssaidi@eecs.umich.edu sTickCompare->deschedule(); 1032948Ssaidi@eecs.umich.edu sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); 1042948Ssaidi@eecs.umich.edu } 1053349Sbinkertn@umich.edu DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); 1062948Ssaidi@eecs.umich.edu break; 1072948Ssaidi@eecs.umich.edu 1082623SN/A case MISCREG_PSTATE: 1092623SN/A setReg(miscReg, val); 1102623SN/A 1112623SN/A case MISCREG_PIL: 1122623SN/A setReg(miscReg, val); 1132623SN/A checkSoftInt(tc); 1142948Ssaidi@eecs.umich.edu break; 1152948Ssaidi@eecs.umich.edu 1162623SN/A case MISCREG_HVER: 1172623SN/A panic("Shouldn't be writing HVER\n"); 1182623SN/A 1192623SN/A case MISCREG_HINTP: 1203349Sbinkertn@umich.edu setReg(miscReg, val); 1212623SN/A if (hintp) 1222657Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_HINTP,0); 1232948Ssaidi@eecs.umich.edu else 1242948Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_HINTP,0); 1252948Ssaidi@eecs.umich.edu break; 1262948Ssaidi@eecs.umich.edu 1272948Ssaidi@eecs.umich.edu case MISCREG_HTBA: 1282948Ssaidi@eecs.umich.edu // clear lower 7 bits on writes. 1292948Ssaidi@eecs.umich.edu setReg(miscReg, val & ULL(~0x7FFF)); 1302948Ssaidi@eecs.umich.edu break; 1312948Ssaidi@eecs.umich.edu 1322948Ssaidi@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_HEAD: 1332948Ssaidi@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_TAIL: 1342948Ssaidi@eecs.umich.edu setReg(miscReg, val); 1352623SN/A if (cpu_mondo_head != cpu_mondo_tail) 1362623SN/A tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0); 1372623SN/A else 1382623SN/A tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0); 1392623SN/A break; 1402623SN/A case MISCREG_QUEUE_DEV_MONDO_HEAD: 1412948Ssaidi@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_TAIL: 1422948Ssaidi@eecs.umich.edu setReg(miscReg, val); 1432623SN/A if (dev_mondo_head != dev_mondo_tail) 1442623SN/A tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0); 1452623SN/A else 1462623SN/A tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0); 1473349Sbinkertn@umich.edu break; 1482623SN/A case MISCREG_QUEUE_RES_ERROR_HEAD: 1492657Ssaidi@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_TAIL: 1502948Ssaidi@eecs.umich.edu setReg(miscReg, val); 1512948Ssaidi@eecs.umich.edu if (res_error_head != res_error_tail) 1522948Ssaidi@eecs.umich.edu tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0); 1532948Ssaidi@eecs.umich.edu else 1542948Ssaidi@eecs.umich.edu tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0); 1552948Ssaidi@eecs.umich.edu break; 1562948Ssaidi@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_HEAD: 1572948Ssaidi@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_TAIL: 1582948Ssaidi@eecs.umich.edu setReg(miscReg, val); 1592948Ssaidi@eecs.umich.edu // This one doesn't have an interrupt to report to the guest OS 1602948Ssaidi@eecs.umich.edu break; 1612623SN/A 1622623SN/A case MISCREG_HSTICK_CMPR: 1632623SN/A if (hSTickCompare == NULL) 1642623SN/A hSTickCompare = new HSTickCompareEvent(this, tc); 1652623SN/A setReg(miscReg, val); 1663349Sbinkertn@umich.edu if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) 1673349Sbinkertn@umich.edu hSTickCompare->deschedule(); 1682623SN/A time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 1693401Sktlim@umich.edu tc->getCpuPtr()->instCount(); 1703401Sktlim@umich.edu if (!(hstick_cmpr & ~mask(63)) && time > 0) { 1713170Sstever@eecs.umich.edu if (hSTickCompare->scheduled()) 1723222Sktlim@umich.edu hSTickCompare->deschedule(); 1733170Sstever@eecs.umich.edu hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); 1742623SN/A } 1752623SN/A DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); 1762856Srdreslin@umich.edu break; 1772856Srdreslin@umich.edu 1782623SN/A case MISCREG_HPSTATE: 1792623SN/A // T1000 spec says impl. dependent val must always be 1 1802623SN/A setReg(miscReg, val | HPSTATE::id); 1812901Ssaidi@eecs.umich.edu#if FULL_SYSTEM 1822798Sktlim@umich.edu if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) 1832798Sktlim@umich.edu tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0); 1842798Sktlim@umich.edu else 1852623SN/A tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0); 1862623SN/A#endif 1872623SN/A break; 1882623SN/A case MISCREG_HTSTATE: 1892623SN/A case MISCREG_STRAND_STS_REG: 1902623SN/A setReg(miscReg, val); 1912623SN/A break; 1922623SN/A 1932623SN/A default: 1942623SN/A panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); 1952623SN/A } 1962623SN/A} 1973349Sbinkertn@umich.edu 1983349Sbinkertn@umich.eduMiscReg 1992644Sstever@eecs.umich.eduMiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) 2002798Sktlim@umich.edu{ 2012839Sktlim@umich.edu switch (miscReg) { 2022623SN/A /* Privileged registers. */ 2032623SN/A case MISCREG_QUEUE_CPU_MONDO_HEAD: 2042623SN/A case MISCREG_QUEUE_CPU_MONDO_TAIL: 205 case MISCREG_QUEUE_DEV_MONDO_HEAD: 206 case MISCREG_QUEUE_DEV_MONDO_TAIL: 207 case MISCREG_QUEUE_RES_ERROR_HEAD: 208 case MISCREG_QUEUE_RES_ERROR_TAIL: 209 case MISCREG_QUEUE_NRES_ERROR_HEAD: 210 case MISCREG_QUEUE_NRES_ERROR_TAIL: 211 case MISCREG_SOFTINT: 212 case MISCREG_TICK_CMPR: 213 case MISCREG_STICK_CMPR: 214 case MISCREG_PIL: 215 case MISCREG_HPSTATE: 216 case MISCREG_HINTP: 217 case MISCREG_HTSTATE: 218 case MISCREG_STRAND_STS_REG: 219 case MISCREG_HSTICK_CMPR: 220 return readReg(miscReg) ; 221 222 case MISCREG_HTBA: 223 return readReg(miscReg) & ULL(~0x7FFF); 224 case MISCREG_HVER: 225 return NWindows | MaxTL << 8 | MaxGL << 16; 226 227 default: 228 panic("Invalid read to FS misc register\n"); 229 } 230} 231/* 232 In Niagra STICK==TICK so this isn't needed 233 case MISCREG_STICK: 234 SparcSystem *sys; 235 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); 236 assert(sys != NULL); 237 return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); 238*/ 239 240 241 242void 243MiscRegFile::processTickCompare(ThreadContext *tc) 244{ 245 panic("tick compare not implemented\n"); 246} 247 248void 249MiscRegFile::processSTickCompare(ThreadContext *tc) 250{ 251 // since our microcode instructions take two cycles we need to check if 252 // we're actually at the correct cycle or we need to wait a little while 253 // more 254 int ticks; 255 ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 256 tc->getCpuPtr()->instCount(); 257 assert(ticks >= 0 && "stick compare missed interrupt cycle"); 258 259 if (ticks == 0) { 260 DPRINTF(Timer, "STick compare cycle reached at %#x\n", 261 (stick_cmpr & mask(63))); 262 if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) { 263 setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); 264 } 265 } else 266 sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 267} 268 269void 270MiscRegFile::processHSTickCompare(ThreadContext *tc) 271{ 272 // since our microcode instructions take two cycles we need to check if 273 // we're actually at the correct cycle or we need to wait a little while 274 // more 275 int ticks; 276 ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 277 tc->getCpuPtr()->instCount(); 278 assert(ticks >= 0 && "hstick compare missed interrupt cycle"); 279 280 if (ticks == 0) { 281 DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", 282 (stick_cmpr & mask(63))); 283 if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) { 284 setRegWithEffect(MISCREG_HINTP, 1, tc); 285 } 286 // Need to do something to cause interrupt to happen here !!! @todo 287 } else 288 hSTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 289} 290 291