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