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