ev5.cc revision 1070
1/* $Id$ */ 2 3#include "arch/alpha/alpha_memory.hh" 4#include "arch/alpha/isa_traits.hh" 5#include "arch/alpha/osfpal.hh" 6#include "base/kgdb.h" 7#include "base/remote_gdb.hh" 8#include "base/stats/events.hh" 9#include "cpu/base_cpu.hh" 10#include "cpu/exec_context.hh" 11#include "cpu/fast_cpu/fast_cpu.hh" 12#include "kern/kernel_stats.hh" 13#include "sim/debug.hh" 14#include "sim/sim_events.hh" 15 16#ifdef FULL_SYSTEM 17 18#ifndef SYSTEM_EV5 19#error This code is only valid for EV5 systems 20#endif 21 22//////////////////////////////////////////////////////////////////////// 23// 24// 25// 26void 27AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) 28{ 29 if (regs->pal_shadow == use_shadow) 30 panic("swap_palshadow: wrong PAL shadow state"); 31 32 regs->pal_shadow = use_shadow; 33 34 for (int i = 0; i < NumIntRegs; i++) { 35 if (reg_redir[i]) { 36 IntReg temp = regs->intRegFile[i]; 37 regs->intRegFile[i] = regs->palregs[i]; 38 regs->palregs[i] = temp; 39 } 40 } 41} 42 43//////////////////////////////////////////////////////////////////////// 44// 45// Machine dependent functions 46// 47void 48AlphaISA::initCPU(RegFile *regs) 49{ 50 initIPRs(regs); 51 // CPU comes up with PAL regs enabled 52 swap_palshadow(regs, true); 53 54 regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault]; 55 regs->npc = regs->pc + sizeof(MachInst); 56} 57 58//////////////////////////////////////////////////////////////////////// 59// 60// alpha exceptions - value equals trap address, update with MD_FAULT_TYPE 61// 62Addr 63AlphaISA::fault_addr[Num_Faults] = { 64 0x0000, /* No_Fault */ 65 0x0001, /* Reset_Fault */ 66 0x0401, /* Machine_Check_Fault */ 67 0x0501, /* Arithmetic_Fault */ 68 0x0101, /* Interrupt_Fault */ 69 0x0201, /* Ndtb_Miss_Fault */ 70 0x0281, /* Pdtb_Miss_Fault */ 71 0x0301, /* Alignment_Fault */ 72 0x0381, /* DTB_Fault_Fault */ 73 0x0381, /* DTB_Acv_Fault */ 74 0x0181, /* ITB_Miss_Fault */ 75 0x0181, /* ITB_Fault_Fault */ 76 0x0081, /* ITB_Acv_Fault */ 77 0x0481, /* Unimplemented_Opcode_Fault */ 78 0x0581, /* Fen_Fault */ 79 0x2001, /* Pal_Fault */ 80 0x0501, /* Integer_Overflow_Fault: maps to Arithmetic_Fault */ 81}; 82 83const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { 84 /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 85 /* 8 */ 1, 1, 1, 1, 1, 1, 1, 0, 86 /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 87 /* 24 */ 0, 1, 0, 0, 0, 0, 0, 0 }; 88 89//////////////////////////////////////////////////////////////////////// 90// 91// 92// 93void 94AlphaISA::initIPRs(RegFile *regs) 95{ 96 uint64_t *ipr = regs->ipr; 97 98 bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); 99 ipr[IPR_PAL_BASE] = PAL_BASE; 100 ipr[IPR_MCSR] = 0x6; 101} 102 103 104template <class XC> 105void 106AlphaISA::processInterrupts(XC *xc) 107{ 108 //Check if there are any outstanding interrupts 109 //Handle the interrupts 110 int ipl = 0; 111 int summary = 0; 112 IntReg *ipr = xc->getIprPtr(); 113 114 check_interrupts = 0; 115 116 if (ipr[IPR_ASTRR]) 117 panic("asynchronous traps not implemented\n"); 118 119 if (ipr[IPR_SIRR]) { 120 for (int i = INTLEVEL_SOFTWARE_MIN; 121 i < INTLEVEL_SOFTWARE_MAX; i++) { 122 if (ipr[IPR_SIRR] & (ULL(1) << i)) { 123 // See table 4-19 of the 21164 hardware reference 124 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; 125 summary |= (ULL(1) << i); 126 } 127 } 128 } 129 130 uint64_t interrupts = xc->intr_status(); 131 132 if (interrupts) { 133 for (int i = INTLEVEL_EXTERNAL_MIN; 134 i < INTLEVEL_EXTERNAL_MAX; i++) { 135 if (interrupts & (ULL(1) << i)) { 136 // See table 4-19 of the 21164 hardware reference 137 ipl = i; 138 summary |= (ULL(1) << i); 139 } 140 } 141 } 142 143 if (ipl && ipl > ipr[IPR_IPLR]) { 144 ipr[IPR_ISR] = summary; 145 ipr[IPR_INTID] = ipl; 146 xc->trap(Interrupt_Fault); 147 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 148 ipr[IPR_IPLR], ipl, summary); 149 } 150 151} 152 153template <class XC> 154void 155AlphaISA::zeroRegisters(XC *xc) 156{ 157 // Insure ISA semantics 158 // (no longer very clean due to the change in setIntReg() in the 159 // cpu model. Consider changing later.) 160 xc->xc->setIntReg(ZeroReg, 0); 161 xc->xc->setFloatRegDouble(ZeroReg, 0.0); 162} 163 164void 165ExecContext::ev5_trap(Fault fault) 166{ 167 DPRINTF(Fault, "Fault %s\n", FaultName(fault)); 168 cpu->recordEvent(csprintf("Fault %s", FaultName(fault))); 169 170 assert(!misspeculating()); 171 kernelStats->fault(fault); 172 173 if (fault == Arithmetic_Fault) 174 panic("Arithmetic traps are unimplemented!"); 175 176 AlphaISA::InternalProcReg *ipr = regs.ipr; 177 178 // exception restart address 179 if (fault != Interrupt_Fault || !PC_PAL(regs.pc)) 180 ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; 181 182 if (fault == Pal_Fault || fault == Arithmetic_Fault /* || 183 fault == Interrupt_Fault && !PC_PAL(regs.pc) */) { 184 // traps... skip faulting instruction 185 ipr[AlphaISA::IPR_EXC_ADDR] += 4; 186 } 187 188 if (!PC_PAL(regs.pc)) 189 AlphaISA::swap_palshadow(®s, true); 190 191 regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; 192 regs.npc = regs.pc + sizeof(MachInst); 193} 194 195 196void 197AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) 198{ 199 InternalProcReg *ipr = regs->ipr; 200 bool use_pc = (fault == No_Fault); 201 202 if (fault == Arithmetic_Fault) 203 panic("arithmetic faults NYI..."); 204 205 // compute exception restart address 206 if (use_pc || fault == Pal_Fault || fault == Arithmetic_Fault) { 207 // traps... skip faulting instruction 208 ipr[IPR_EXC_ADDR] = regs->pc + 4; 209 } else { 210 // fault, post fault at excepting instruction 211 ipr[IPR_EXC_ADDR] = regs->pc; 212 } 213 214 // jump to expection address (PAL PC bit set here as well...) 215 if (!use_pc) 216 regs->npc = ipr[IPR_PAL_BASE] + fault_addr[fault]; 217 else 218 regs->npc = ipr[IPR_PAL_BASE] + pc; 219 220 // that's it! (orders of magnitude less painful than x86) 221} 222 223bool AlphaISA::check_interrupts = false; 224 225Fault 226ExecContext::hwrei() 227{ 228 uint64_t *ipr = regs.ipr; 229 230 if (!PC_PAL(regs.pc)) 231 return Unimplemented_Opcode_Fault; 232 233 setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); 234 235 if (!misspeculating()) { 236 kernelStats->hwrei(); 237 238 if ((ipr[AlphaISA::IPR_EXC_ADDR] & 1) == 0) 239 AlphaISA::swap_palshadow(®s, false); 240 241 AlphaISA::check_interrupts = true; 242 } 243 244 // FIXME: XXX check for interrupts? XXX 245 return No_Fault; 246} 247 248uint64_t 249ExecContext::readIpr(int idx, Fault &fault) 250{ 251 uint64_t *ipr = regs.ipr; 252 uint64_t retval = 0; // return value, default 0 253 254 switch (idx) { 255 case AlphaISA::IPR_PALtemp0: 256 case AlphaISA::IPR_PALtemp1: 257 case AlphaISA::IPR_PALtemp2: 258 case AlphaISA::IPR_PALtemp3: 259 case AlphaISA::IPR_PALtemp4: 260 case AlphaISA::IPR_PALtemp5: 261 case AlphaISA::IPR_PALtemp6: 262 case AlphaISA::IPR_PALtemp7: 263 case AlphaISA::IPR_PALtemp8: 264 case AlphaISA::IPR_PALtemp9: 265 case AlphaISA::IPR_PALtemp10: 266 case AlphaISA::IPR_PALtemp11: 267 case AlphaISA::IPR_PALtemp12: 268 case AlphaISA::IPR_PALtemp13: 269 case AlphaISA::IPR_PALtemp14: 270 case AlphaISA::IPR_PALtemp15: 271 case AlphaISA::IPR_PALtemp16: 272 case AlphaISA::IPR_PALtemp17: 273 case AlphaISA::IPR_PALtemp18: 274 case AlphaISA::IPR_PALtemp19: 275 case AlphaISA::IPR_PALtemp20: 276 case AlphaISA::IPR_PALtemp21: 277 case AlphaISA::IPR_PALtemp22: 278 case AlphaISA::IPR_PALtemp23: 279 case AlphaISA::IPR_PAL_BASE: 280 281 case AlphaISA::IPR_IVPTBR: 282 case AlphaISA::IPR_DC_MODE: 283 case AlphaISA::IPR_MAF_MODE: 284 case AlphaISA::IPR_ISR: 285 case AlphaISA::IPR_EXC_ADDR: 286 case AlphaISA::IPR_IC_PERR_STAT: 287 case AlphaISA::IPR_DC_PERR_STAT: 288 case AlphaISA::IPR_MCSR: 289 case AlphaISA::IPR_ASTRR: 290 case AlphaISA::IPR_ASTER: 291 case AlphaISA::IPR_SIRR: 292 case AlphaISA::IPR_ICSR: 293 case AlphaISA::IPR_ICM: 294 case AlphaISA::IPR_DTB_CM: 295 case AlphaISA::IPR_IPLR: 296 case AlphaISA::IPR_INTID: 297 case AlphaISA::IPR_PMCTR: 298 // no side-effect 299 retval = ipr[idx]; 300 break; 301 302 case AlphaISA::IPR_CC: 303 retval |= ipr[idx] & ULL(0xffffffff00000000); 304 retval |= curTick & ULL(0x00000000ffffffff); 305 break; 306 307 case AlphaISA::IPR_VA: 308 retval = ipr[idx]; 309 break; 310 311 case AlphaISA::IPR_VA_FORM: 312 case AlphaISA::IPR_MM_STAT: 313 case AlphaISA::IPR_IFAULT_VA_FORM: 314 case AlphaISA::IPR_EXC_MASK: 315 case AlphaISA::IPR_EXC_SUM: 316 retval = ipr[idx]; 317 break; 318 319 case AlphaISA::IPR_DTB_PTE: 320 { 321 AlphaISA::PTE &pte = dtb->index(!misspeculating()); 322 323 retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; 324 retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; 325 retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12; 326 retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1; 327 retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2; 328 retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4; 329 retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57; 330 } 331 break; 332 333 // write only registers 334 case AlphaISA::IPR_HWINT_CLR: 335 case AlphaISA::IPR_SL_XMIT: 336 case AlphaISA::IPR_DC_FLUSH: 337 case AlphaISA::IPR_IC_FLUSH: 338 case AlphaISA::IPR_ALT_MODE: 339 case AlphaISA::IPR_DTB_IA: 340 case AlphaISA::IPR_DTB_IAP: 341 case AlphaISA::IPR_ITB_IA: 342 case AlphaISA::IPR_ITB_IAP: 343 fault = Unimplemented_Opcode_Fault; 344 break; 345 346 default: 347 // invalid IPR 348 fault = Unimplemented_Opcode_Fault; 349 break; 350 } 351 352 return retval; 353} 354 355#ifdef DEBUG 356// Cause the simulator to break when changing to the following IPL 357int break_ipl = -1; 358#endif 359 360Fault 361ExecContext::setIpr(int idx, uint64_t val) 362{ 363 uint64_t *ipr = regs.ipr; 364 uint64_t old; 365 366 if (misspeculating()) 367 return No_Fault; 368 369 switch (idx) { 370 case AlphaISA::IPR_PALtemp0: 371 case AlphaISA::IPR_PALtemp1: 372 case AlphaISA::IPR_PALtemp2: 373 case AlphaISA::IPR_PALtemp3: 374 case AlphaISA::IPR_PALtemp4: 375 case AlphaISA::IPR_PALtemp5: 376 case AlphaISA::IPR_PALtemp6: 377 case AlphaISA::IPR_PALtemp7: 378 case AlphaISA::IPR_PALtemp8: 379 case AlphaISA::IPR_PALtemp9: 380 case AlphaISA::IPR_PALtemp10: 381 case AlphaISA::IPR_PALtemp11: 382 case AlphaISA::IPR_PALtemp12: 383 case AlphaISA::IPR_PALtemp13: 384 case AlphaISA::IPR_PALtemp14: 385 case AlphaISA::IPR_PALtemp15: 386 case AlphaISA::IPR_PALtemp16: 387 case AlphaISA::IPR_PALtemp17: 388 case AlphaISA::IPR_PALtemp18: 389 case AlphaISA::IPR_PALtemp19: 390 case AlphaISA::IPR_PALtemp20: 391 case AlphaISA::IPR_PALtemp21: 392 case AlphaISA::IPR_PALtemp22: 393 case AlphaISA::IPR_PAL_BASE: 394 case AlphaISA::IPR_IC_PERR_STAT: 395 case AlphaISA::IPR_DC_PERR_STAT: 396 case AlphaISA::IPR_PMCTR: 397 // write entire quad w/ no side-effect 398 ipr[idx] = val; 399 break; 400 401 case AlphaISA::IPR_CC_CTL: 402 // This IPR resets the cycle counter. We assume this only 403 // happens once... let's verify that. 404 assert(ipr[idx] == 0); 405 ipr[idx] = 1; 406 break; 407 408 case AlphaISA::IPR_CC: 409 // This IPR only writes the upper 64 bits. It's ok to write 410 // all 64 here since we mask out the lower 32 in rpcc (see 411 // isa_desc). 412 ipr[idx] = val; 413 break; 414 415 case AlphaISA::IPR_PALtemp23: 416 // write entire quad w/ no side-effect 417 old = ipr[idx]; 418 ipr[idx] = val; 419 kernelStats->context(old, val); 420 break; 421 422 case AlphaISA::IPR_DTB_PTE: 423 // write entire quad w/ no side-effect, tag is forthcoming 424 ipr[idx] = val; 425 break; 426 427 case AlphaISA::IPR_EXC_ADDR: 428 // second least significant bit in PC is always zero 429 ipr[idx] = val & ~2; 430 break; 431 432 case AlphaISA::IPR_ASTRR: 433 case AlphaISA::IPR_ASTER: 434 // only write least significant four bits - privilege mask 435 ipr[idx] = val & 0xf; 436 break; 437 438 case AlphaISA::IPR_IPLR: 439#ifdef DEBUG 440 if (break_ipl != -1 && break_ipl == (val & 0x1f)) 441 debug_break(); 442#endif 443 444 // only write least significant five bits - interrupt level 445 ipr[idx] = val & 0x1f; 446 kernelStats->swpipl(ipr[idx]); 447 break; 448 449 case AlphaISA::IPR_DTB_CM: 450 kernelStats->mode((val & 0x18) != 0); 451 452 case AlphaISA::IPR_ICM: 453 // only write two mode bits - processor mode 454 ipr[idx] = val & 0x18; 455 break; 456 457 case AlphaISA::IPR_ALT_MODE: 458 // only write two mode bits - processor mode 459 ipr[idx] = val & 0x18; 460 break; 461 462 case AlphaISA::IPR_MCSR: 463 // more here after optimization... 464 ipr[idx] = val; 465 break; 466 467 case AlphaISA::IPR_SIRR: 468 // only write software interrupt mask 469 ipr[idx] = val & 0x7fff0; 470 break; 471 472 case AlphaISA::IPR_ICSR: 473 ipr[idx] = val & ULL(0xffffff0300); 474 break; 475 476 case AlphaISA::IPR_IVPTBR: 477 case AlphaISA::IPR_MVPTBR: 478 ipr[idx] = val & ULL(0xffffffffc0000000); 479 break; 480 481 case AlphaISA::IPR_DC_TEST_CTL: 482 ipr[idx] = val & 0x1ffb; 483 break; 484 485 case AlphaISA::IPR_DC_MODE: 486 case AlphaISA::IPR_MAF_MODE: 487 ipr[idx] = val & 0x3f; 488 break; 489 490 case AlphaISA::IPR_ITB_ASN: 491 ipr[idx] = val & 0x7f0; 492 break; 493 494 case AlphaISA::IPR_DTB_ASN: 495 ipr[idx] = val & ULL(0xfe00000000000000); 496 break; 497 498 case AlphaISA::IPR_EXC_SUM: 499 case AlphaISA::IPR_EXC_MASK: 500 // any write to this register clears it 501 ipr[idx] = 0; 502 break; 503 504 case AlphaISA::IPR_INTID: 505 case AlphaISA::IPR_SL_RCV: 506 case AlphaISA::IPR_MM_STAT: 507 case AlphaISA::IPR_ITB_PTE_TEMP: 508 case AlphaISA::IPR_DTB_PTE_TEMP: 509 // read-only registers 510 return Unimplemented_Opcode_Fault; 511 512 case AlphaISA::IPR_HWINT_CLR: 513 case AlphaISA::IPR_SL_XMIT: 514 case AlphaISA::IPR_DC_FLUSH: 515 case AlphaISA::IPR_IC_FLUSH: 516 // the following are write only 517 ipr[idx] = val; 518 break; 519 520 case AlphaISA::IPR_DTB_IA: 521 // really a control write 522 ipr[idx] = 0; 523 524 dtb->flushAll(); 525 break; 526 527 case AlphaISA::IPR_DTB_IAP: 528 // really a control write 529 ipr[idx] = 0; 530 531 dtb->flushProcesses(); 532 break; 533 534 case AlphaISA::IPR_DTB_IS: 535 // really a control write 536 ipr[idx] = val; 537 538 dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); 539 break; 540 541 case AlphaISA::IPR_DTB_TAG: { 542 struct AlphaISA::PTE pte; 543 544 // FIXME: granularity hints NYI... 545 if (DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) 546 panic("PTE GH field != 0"); 547 548 // write entire quad 549 ipr[idx] = val; 550 551 // construct PTE for new entry 552 pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); 553 pte.xre = DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); 554 pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); 555 pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); 556 pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); 557 pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); 558 pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); 559 560 // insert new TAG/PTE value into data TLB 561 dtb->insert(val, pte); 562 } 563 break; 564 565 case AlphaISA::IPR_ITB_PTE: { 566 struct AlphaISA::PTE pte; 567 568 // FIXME: granularity hints NYI... 569 if (ITB_PTE_GH(val) != 0) 570 panic("PTE GH field != 0"); 571 572 // write entire quad 573 ipr[idx] = val; 574 575 // construct PTE for new entry 576 pte.ppn = ITB_PTE_PPN(val); 577 pte.xre = ITB_PTE_XRE(val); 578 pte.xwe = 0; 579 pte.fonr = ITB_PTE_FONR(val); 580 pte.fonw = ITB_PTE_FONW(val); 581 pte.asma = ITB_PTE_ASMA(val); 582 pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); 583 584 // insert new TAG/PTE value into data TLB 585 itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); 586 } 587 break; 588 589 case AlphaISA::IPR_ITB_IA: 590 // really a control write 591 ipr[idx] = 0; 592 593 itb->flushAll(); 594 break; 595 596 case AlphaISA::IPR_ITB_IAP: 597 // really a control write 598 ipr[idx] = 0; 599 600 itb->flushProcesses(); 601 break; 602 603 case AlphaISA::IPR_ITB_IS: 604 // really a control write 605 ipr[idx] = val; 606 607 itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); 608 break; 609 610 default: 611 // invalid IPR 612 return Unimplemented_Opcode_Fault; 613 } 614 615 // no error... 616 return No_Fault; 617} 618 619/** 620 * Check for special simulator handling of specific PAL calls. 621 * If return value is false, actual PAL call will be suppressed. 622 */ 623bool 624ExecContext::simPalCheck(int palFunc) 625{ 626 kernelStats->callpal(palFunc); 627 628 switch (palFunc) { 629 case PAL::halt: 630 halt(); 631 if (--System::numSystemsRunning == 0) 632 new SimExitEvent("all cpus halted"); 633 break; 634 635 case PAL::bpt: 636 case PAL::bugchk: 637 if (system->breakpoint()) 638 return false; 639 break; 640 } 641 642 return true; 643} 644 645//Forward instantiation for FastCPU object 646template 647void AlphaISA::processInterrupts(FastCPU *xc); 648 649//Forward instantiation for FastCPU object 650template 651void AlphaISA::zeroRegisters(FastCPU *xc); 652 653#endif // FULL_SYSTEM 654