ev5.cc revision 7627:3b0c4b819651
1/* 2 * Copyright (c) 2002-2005 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 * Authors: Steve Reinhardt 29 * Nathan Binkert 30 */ 31 32#include "arch/alpha/faults.hh" 33#include "arch/alpha/isa_traits.hh" 34#include "arch/alpha/kernel_stats.hh" 35#include "arch/alpha/osfpal.hh" 36#include "arch/alpha/tlb.hh" 37#include "base/cp_annotate.hh" 38#include "base/debug.hh" 39#include "config/full_system.hh" 40#include "cpu/base.hh" 41#include "cpu/simple_thread.hh" 42#include "cpu/thread_context.hh" 43#include "sim/sim_exit.hh" 44 45namespace AlphaISA { 46 47#if FULL_SYSTEM 48 49//////////////////////////////////////////////////////////////////////// 50// 51// Machine dependent functions 52// 53void 54initCPU(ThreadContext *tc, int cpuId) 55{ 56 initIPRs(tc, cpuId); 57 58 tc->setIntReg(16, cpuId); 59 tc->setIntReg(0, cpuId); 60 61 AlphaFault *reset = new ResetFault; 62 63 tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect()); 64 tc->setNextPC(tc->readPC() + sizeof(MachInst)); 65 66 delete reset; 67} 68 69template <class CPU> 70void 71zeroRegisters(CPU *cpu) 72{ 73 // Insure ISA semantics 74 // (no longer very clean due to the change in setIntReg() in the 75 // cpu model. Consider changing later.) 76 cpu->thread->setIntReg(ZeroReg, 0); 77 cpu->thread->setFloatReg(ZeroReg, 0.0); 78} 79 80#endif 81 82//////////////////////////////////////////////////////////////////////// 83// 84// 85// 86void 87initIPRs(ThreadContext *tc, int cpuId) 88{ 89 for (int i = 0; i < NumInternalProcRegs; ++i) { 90 tc->setMiscRegNoEffect(i, 0); 91 } 92 93 tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase); 94 tc->setMiscRegNoEffect(IPR_MCSR, 0x6); 95 tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId); 96} 97 98MiscReg 99ISA::readIpr(int idx, ThreadContext *tc) 100{ 101 uint64_t retval = 0; // return value, default 0 102 103 switch (idx) { 104 case IPR_PALtemp0: 105 case IPR_PALtemp1: 106 case IPR_PALtemp2: 107 case IPR_PALtemp3: 108 case IPR_PALtemp4: 109 case IPR_PALtemp5: 110 case IPR_PALtemp6: 111 case IPR_PALtemp7: 112 case IPR_PALtemp8: 113 case IPR_PALtemp9: 114 case IPR_PALtemp10: 115 case IPR_PALtemp11: 116 case IPR_PALtemp12: 117 case IPR_PALtemp13: 118 case IPR_PALtemp14: 119 case IPR_PALtemp15: 120 case IPR_PALtemp16: 121 case IPR_PALtemp17: 122 case IPR_PALtemp18: 123 case IPR_PALtemp19: 124 case IPR_PALtemp20: 125 case IPR_PALtemp21: 126 case IPR_PALtemp22: 127 case IPR_PALtemp23: 128 case IPR_PAL_BASE: 129 130 case IPR_IVPTBR: 131 case IPR_DC_MODE: 132 case IPR_MAF_MODE: 133 case IPR_ISR: 134 case IPR_EXC_ADDR: 135 case IPR_IC_PERR_STAT: 136 case IPR_DC_PERR_STAT: 137 case IPR_MCSR: 138 case IPR_ASTRR: 139 case IPR_ASTER: 140 case IPR_SIRR: 141 case IPR_ICSR: 142 case IPR_ICM: 143 case IPR_DTB_CM: 144 case IPR_IPLR: 145 case IPR_INTID: 146 case IPR_PMCTR: 147 // no side-effect 148 retval = ipr[idx]; 149 break; 150 151 case IPR_CC: 152 retval |= ipr[idx] & ULL(0xffffffff00000000); 153 retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); 154 break; 155 156 case IPR_VA: 157 retval = ipr[idx]; 158 break; 159 160 case IPR_VA_FORM: 161 case IPR_MM_STAT: 162 case IPR_IFAULT_VA_FORM: 163 case IPR_EXC_MASK: 164 case IPR_EXC_SUM: 165 retval = ipr[idx]; 166 break; 167 168 case IPR_DTB_PTE: 169 { 170 TlbEntry &entry 171 = tc->getDTBPtr()->index(!tc->misspeculating()); 172 173 retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32; 174 retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8; 175 retval |= ((uint64_t)entry.xwe & ULL(0xf)) << 12; 176 retval |= ((uint64_t)entry.fonr & ULL(0x1)) << 1; 177 retval |= ((uint64_t)entry.fonw & ULL(0x1))<< 2; 178 retval |= ((uint64_t)entry.asma & ULL(0x1)) << 4; 179 retval |= ((uint64_t)entry.asn & ULL(0x7f)) << 57; 180 } 181 break; 182 183 // write only registers 184 case IPR_HWINT_CLR: 185 case IPR_SL_XMIT: 186 case IPR_DC_FLUSH: 187 case IPR_IC_FLUSH: 188 case IPR_ALT_MODE: 189 case IPR_DTB_IA: 190 case IPR_DTB_IAP: 191 case IPR_ITB_IA: 192 case IPR_ITB_IAP: 193 panic("Tried to read write only register %d\n", idx); 194 break; 195 196 default: 197 // invalid IPR 198 panic("Tried to read from invalid ipr %d\n", idx); 199 break; 200 } 201 202 return retval; 203} 204 205#ifdef DEBUG 206// Cause the simulator to break when changing to the following IPL 207int break_ipl = -1; 208#endif 209 210void 211ISA::setIpr(int idx, uint64_t val, ThreadContext *tc) 212{ 213 uint64_t old; 214 215 if (tc->misspeculating()) 216 return; 217 218 switch (idx) { 219 case IPR_PALtemp0: 220 case IPR_PALtemp1: 221 case IPR_PALtemp2: 222 case IPR_PALtemp3: 223 case IPR_PALtemp4: 224 case IPR_PALtemp5: 225 case IPR_PALtemp6: 226 case IPR_PALtemp7: 227 case IPR_PALtemp8: 228 case IPR_PALtemp9: 229 case IPR_PALtemp10: 230 case IPR_PALtemp11: 231 case IPR_PALtemp12: 232 case IPR_PALtemp13: 233 case IPR_PALtemp14: 234 case IPR_PALtemp15: 235 case IPR_PALtemp16: 236 case IPR_PALtemp17: 237 case IPR_PALtemp18: 238 case IPR_PALtemp19: 239 case IPR_PALtemp20: 240 case IPR_PALtemp21: 241 case IPR_PALtemp22: 242 case IPR_PAL_BASE: 243 case IPR_IC_PERR_STAT: 244 case IPR_DC_PERR_STAT: 245 case IPR_PMCTR: 246 // write entire quad w/ no side-effect 247 ipr[idx] = val; 248 break; 249 250 case IPR_CC_CTL: 251 // This IPR resets the cycle counter. We assume this only 252 // happens once... let's verify that. 253 assert(ipr[idx] == 0); 254 ipr[idx] = 1; 255 break; 256 257 case IPR_CC: 258 // This IPR only writes the upper 64 bits. It's ok to write 259 // all 64 here since we mask out the lower 32 in rpcc (see 260 // isa_desc). 261 ipr[idx] = val; 262 break; 263 264 case IPR_PALtemp23: 265 // write entire quad w/ no side-effect 266 old = ipr[idx]; 267 ipr[idx] = val; 268#if FULL_SYSTEM 269 if (tc->getKernelStats()) 270 tc->getKernelStats()->context(old, val, tc); 271#endif 272 break; 273 274 case IPR_DTB_PTE: 275 // write entire quad w/ no side-effect, tag is forthcoming 276 ipr[idx] = val; 277 break; 278 279 case IPR_EXC_ADDR: 280 // second least significant bit in PC is always zero 281 ipr[idx] = val & ~2; 282 break; 283 284 case IPR_ASTRR: 285 case IPR_ASTER: 286 // only write least significant four bits - privilege mask 287 ipr[idx] = val & 0xf; 288 break; 289 290 case IPR_IPLR: 291#ifdef DEBUG 292 if (break_ipl != -1 && break_ipl == (int)(val & 0x1f)) 293 debug_break(); 294#endif 295 296 // only write least significant five bits - interrupt level 297 ipr[idx] = val & 0x1f; 298#if FULL_SYSTEM 299 if (tc->getKernelStats()) 300 tc->getKernelStats()->swpipl(ipr[idx]); 301#endif 302 break; 303 304 case IPR_DTB_CM: 305#if FULL_SYSTEM 306 if (val & 0x18) { 307 if (tc->getKernelStats()) 308 tc->getKernelStats()->mode(Kernel::user, tc); 309 } else { 310 if (tc->getKernelStats()) 311 tc->getKernelStats()->mode(Kernel::kernel, tc); 312 } 313#endif 314 315 case IPR_ICM: 316 // only write two mode bits - processor mode 317 ipr[idx] = val & 0x18; 318 break; 319 320 case IPR_ALT_MODE: 321 // only write two mode bits - processor mode 322 ipr[idx] = val & 0x18; 323 break; 324 325 case IPR_MCSR: 326 // more here after optimization... 327 ipr[idx] = val; 328 break; 329 330 case IPR_SIRR: 331 // only write software interrupt mask 332 ipr[idx] = val & 0x7fff0; 333 break; 334 335 case IPR_ICSR: 336 ipr[idx] = val & ULL(0xffffff0300); 337 break; 338 339 case IPR_IVPTBR: 340 case IPR_MVPTBR: 341 ipr[idx] = val & ULL(0xffffffffc0000000); 342 break; 343 344 case IPR_DC_TEST_CTL: 345 ipr[idx] = val & 0x1ffb; 346 break; 347 348 case IPR_DC_MODE: 349 case IPR_MAF_MODE: 350 ipr[idx] = val & 0x3f; 351 break; 352 353 case IPR_ITB_ASN: 354 ipr[idx] = val & 0x7f0; 355 break; 356 357 case IPR_DTB_ASN: 358 ipr[idx] = val & ULL(0xfe00000000000000); 359 break; 360 361 case IPR_EXC_SUM: 362 case IPR_EXC_MASK: 363 // any write to this register clears it 364 ipr[idx] = 0; 365 break; 366 367 case IPR_INTID: 368 case IPR_SL_RCV: 369 case IPR_MM_STAT: 370 case IPR_ITB_PTE_TEMP: 371 case IPR_DTB_PTE_TEMP: 372 // read-only registers 373 panic("Tried to write read only ipr %d\n", idx); 374 375 case IPR_HWINT_CLR: 376 case IPR_SL_XMIT: 377 case IPR_DC_FLUSH: 378 case IPR_IC_FLUSH: 379 // the following are write only 380 ipr[idx] = val; 381 break; 382 383 case IPR_DTB_IA: 384 // really a control write 385 ipr[idx] = 0; 386 387 tc->getDTBPtr()->flushAll(); 388 break; 389 390 case IPR_DTB_IAP: 391 // really a control write 392 ipr[idx] = 0; 393 394 tc->getDTBPtr()->flushProcesses(); 395 break; 396 397 case IPR_DTB_IS: 398 // really a control write 399 ipr[idx] = val; 400 401 tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN])); 402 break; 403 404 case IPR_DTB_TAG: { 405 struct TlbEntry entry; 406 407 // FIXME: granularity hints NYI... 408 if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0) 409 panic("PTE GH field != 0"); 410 411 // write entire quad 412 ipr[idx] = val; 413 414 // construct PTE for new entry 415 entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]); 416 entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]); 417 entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]); 418 entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]); 419 entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]); 420 entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]); 421 entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]); 422 423 // insert new TAG/PTE value into data TLB 424 tc->getDTBPtr()->insert(val, entry); 425 } 426 break; 427 428 case IPR_ITB_PTE: { 429 struct TlbEntry entry; 430 431 // FIXME: granularity hints NYI... 432 if (ITB_PTE_GH(val) != 0) 433 panic("PTE GH field != 0"); 434 435 // write entire quad 436 ipr[idx] = val; 437 438 // construct PTE for new entry 439 entry.ppn = ITB_PTE_PPN(val); 440 entry.xre = ITB_PTE_XRE(val); 441 entry.xwe = 0; 442 entry.fonr = ITB_PTE_FONR(val); 443 entry.fonw = ITB_PTE_FONW(val); 444 entry.asma = ITB_PTE_ASMA(val); 445 entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]); 446 447 // insert new TAG/PTE value into data TLB 448 tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry); 449 } 450 break; 451 452 case IPR_ITB_IA: 453 // really a control write 454 ipr[idx] = 0; 455 456 tc->getITBPtr()->flushAll(); 457 break; 458 459 case IPR_ITB_IAP: 460 // really a control write 461 ipr[idx] = 0; 462 463 tc->getITBPtr()->flushProcesses(); 464 break; 465 466 case IPR_ITB_IS: 467 // really a control write 468 ipr[idx] = val; 469 470 tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN])); 471 break; 472 473 default: 474 // invalid IPR 475 panic("Tried to write to invalid ipr %d\n", idx); 476 } 477 478 // no error... 479} 480 481void 482copyIprs(ThreadContext *src, ThreadContext *dest) 483{ 484 for (int i = 0; i < NumInternalProcRegs; ++i) 485 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 486} 487 488} // namespace AlphaISA 489 490#if FULL_SYSTEM 491 492using namespace AlphaISA; 493 494Fault 495SimpleThread::hwrei() 496{ 497 if (!(readPC() & 0x3)) 498 return new UnimplementedOpcodeFault; 499 500 setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); 501 502 CPA::cpa()->swAutoBegin(tc, readNextPC()); 503 504 if (!misspeculating()) { 505 if (kernelStats) 506 kernelStats->hwrei(); 507 } 508 509 // FIXME: XXX check for interrupts? XXX 510 return NoFault; 511} 512 513/** 514 * Check for special simulator handling of specific PAL calls. 515 * If return value is false, actual PAL call will be suppressed. 516 */ 517bool 518SimpleThread::simPalCheck(int palFunc) 519{ 520 if (kernelStats) 521 kernelStats->callpal(palFunc, tc); 522 523 switch (palFunc) { 524 case PAL::halt: 525 halt(); 526 if (--System::numSystemsRunning == 0) 527 exitSimLoop("all cpus halted"); 528 break; 529 530 case PAL::bpt: 531 case PAL::bugchk: 532 if (system->breakpoint()) 533 return false; 534 break; 535 } 536 537 return true; 538} 539 540#endif // FULL_SYSTEM 541