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