ua2005.cc revision 3935:ef6891f64dc8
1/* 2 * Copyright (c) 2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include "arch/sparc/miscregfile.hh" 30#include "base/bitfield.hh" 31#include "base/trace.hh" 32#include "cpu/base.hh" 33#include "cpu/thread_context.hh" 34 35using namespace SparcISA; 36 37void 38MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, 39 ThreadContext *tc) 40{ 41 int64_t time; 42 switch (miscReg) { 43 /* Full system only ASRs */ 44 case MISCREG_SOFTINT: 45 setReg(miscReg, val);; 46 break; 47 48 case MISCREG_SOFTINT_CLR: 49 return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); 50 case MISCREG_SOFTINT_SET: 51 tc->getCpuPtr()->post_interrupt(soft_interrupt); 52 return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); 53 54 case MISCREG_TICK_CMPR: 55 if (tickCompare == NULL) 56 tickCompare = new TickCompareEvent(this, tc); 57 setReg(miscReg, val); 58 if ((tick_cmpr & mask(63)) && tickCompare->scheduled()) 59 tickCompare->deschedule(); 60 time = (tick_cmpr & mask(63)) - (tick & mask(63)); 61 if (!(tick_cmpr & ~mask(63)) && time > 0) 62 tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); 63 panic("writing to TICK compare register %#X\n", val); 64 break; 65 66 case MISCREG_STICK_CMPR: 67 if (sTickCompare == NULL) 68 sTickCompare = new STickCompareEvent(this, tc); 69 setReg(miscReg, val); 70 if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) 71 sTickCompare->deschedule(); 72 time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 73 tc->getCpuPtr()->instCount(); 74 if (!(stick_cmpr & ~mask(63)) && time > 0) 75 sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); 76 DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); 77 break; 78 79 case MISCREG_PSTATE: 80 setReg(miscReg, val); 81 82 case MISCREG_PIL: 83 setReg(miscReg, val); 84 break; 85 86 case MISCREG_HVER: 87 panic("Shouldn't be writing HVER\n"); 88 89 case MISCREG_HINTP: 90 setReg(miscReg, val); 91 92 case MISCREG_HTBA: 93 // clear lower 7 bits on writes. 94 setReg(miscReg, val & ULL(~0x7FFF)); 95 break; 96 97 case MISCREG_QUEUE_CPU_MONDO_HEAD: 98 case MISCREG_QUEUE_CPU_MONDO_TAIL: 99 case MISCREG_QUEUE_DEV_MONDO_HEAD: 100 case MISCREG_QUEUE_DEV_MONDO_TAIL: 101 case MISCREG_QUEUE_RES_ERROR_HEAD: 102 case MISCREG_QUEUE_RES_ERROR_TAIL: 103 case MISCREG_QUEUE_NRES_ERROR_HEAD: 104 case MISCREG_QUEUE_NRES_ERROR_TAIL: 105 setReg(miscReg, val); 106 //do something to post mondo interrupt 107 break; 108 109 case MISCREG_HSTICK_CMPR: 110 if (hSTickCompare == NULL) 111 hSTickCompare = new HSTickCompareEvent(this, tc); 112 setReg(miscReg, val); 113 if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) 114 hSTickCompare->deschedule(); 115 time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 116 tc->getCpuPtr()->instCount(); 117 if (!(hstick_cmpr & ~mask(63)) && time > 0) 118 hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); 119 DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); 120 break; 121 122 case MISCREG_HPSTATE: 123 // T1000 spec says impl. dependent val must always be 1 124 setReg(miscReg, val | HPSTATE::id); 125 break; 126 case MISCREG_HTSTATE: 127 case MISCREG_STRAND_STS_REG: 128 setReg(miscReg, val); 129 break; 130 131 default: 132 panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); 133 } 134} 135 136MiscReg 137MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) 138{ 139 switch (miscReg) { 140 /* Privileged registers. */ 141 case MISCREG_QUEUE_CPU_MONDO_HEAD: 142 case MISCREG_QUEUE_CPU_MONDO_TAIL: 143 case MISCREG_QUEUE_DEV_MONDO_HEAD: 144 case MISCREG_QUEUE_DEV_MONDO_TAIL: 145 case MISCREG_QUEUE_RES_ERROR_HEAD: 146 case MISCREG_QUEUE_RES_ERROR_TAIL: 147 case MISCREG_QUEUE_NRES_ERROR_HEAD: 148 case MISCREG_QUEUE_NRES_ERROR_TAIL: 149 case MISCREG_SOFTINT: 150 case MISCREG_TICK_CMPR: 151 case MISCREG_STICK_CMPR: 152 case MISCREG_PIL: 153 case MISCREG_HPSTATE: 154 case MISCREG_HINTP: 155 case MISCREG_HTSTATE: 156 case MISCREG_STRAND_STS_REG: 157 case MISCREG_HSTICK_CMPR: 158 return readReg(miscReg) ; 159 160 case MISCREG_HTBA: 161 return readReg(miscReg) & ULL(~0x7FFF); 162 case MISCREG_HVER: 163 return NWindows | MaxTL << 8 | MaxGL << 16; 164 165 default: 166 panic("Invalid read to FS misc register\n"); 167 } 168} 169/* 170 In Niagra STICK==TICK so this isn't needed 171 case MISCREG_STICK: 172 SparcSystem *sys; 173 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); 174 assert(sys != NULL); 175 return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); 176*/ 177 178 179 180void 181MiscRegFile::processTickCompare(ThreadContext *tc) 182{ 183 panic("tick compare not implemented\n"); 184} 185 186void 187MiscRegFile::processSTickCompare(ThreadContext *tc) 188{ 189 // since our microcode instructions take two cycles we need to check if 190 // we're actually at the correct cycle or we need to wait a little while 191 // more 192 int ticks; 193 ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 194 tc->getCpuPtr()->instCount(); 195 assert(ticks >= 0 && "stick compare missed interrupt cycle"); 196 197 if (ticks == 0) { 198 DPRINTF(Timer, "STick compare cycle reached at %#x\n", 199 (stick_cmpr & mask(63))); 200 if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) { 201 tc->getCpuPtr()->post_interrupt(soft_interrupt); 202 setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); 203 } 204 } else 205 sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 206} 207 208void 209MiscRegFile::processHSTickCompare(ThreadContext *tc) 210{ 211 // since our microcode instructions take two cycles we need to check if 212 // we're actually at the correct cycle or we need to wait a little while 213 // more 214 int ticks; 215 ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 216 tc->getCpuPtr()->instCount(); 217 assert(ticks >= 0 && "hstick compare missed interrupt cycle"); 218 219 if (ticks == 0) { 220 DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", 221 (stick_cmpr & mask(63))); 222 if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) { 223 setRegWithEffect(MISCREG_HINTP, 1, tc); 224 tc->getCpuPtr()->post_interrupt(hstick_match); 225 } 226 // Need to do something to cause interrupt to happen here !!! @todo 227 } else 228 sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); 229} 230 231