faults.cc (3949:b6664282d899) | faults.cc (3972:2c65c89843c5) |
---|---|
1/* 2 * Copyright (c) 2003-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; --- 183 unchanged lines hidden (view full) --- 192 193//XXX This trap is apparently dropped from ua2005 194/*template<> SparcFaultBase::FaultVals 195 SparcFault<AsyncDataError>::vals = 196 {"async_data", 0x040, 2, {H, H, H}};*/ 197 198template<> SparcFaultBase::FaultVals 199 SparcFault<InterruptLevelN>::vals = | 1/* 2 * Copyright (c) 2003-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; --- 183 unchanged lines hidden (view full) --- 192 193//XXX This trap is apparently dropped from ua2005 194/*template<> SparcFaultBase::FaultVals 195 SparcFault<AsyncDataError>::vals = 196 {"async_data", 0x040, 2, {H, H, H}};*/ 197 198template<> SparcFaultBase::FaultVals 199 SparcFault<InterruptLevelN>::vals = |
200 {"interrupt_level_n", 0x041, 0, {P, P, SH}}; | 200 {"interrupt_level_n", 0x040, 0, {P, P, SH}}; |
201 202template<> SparcFaultBase::FaultVals 203 SparcFault<HstickMatch>::vals = 204 {"hstick_match", 0x05E, 1601, {H, H, H}}; 205 206template<> SparcFaultBase::FaultVals 207 SparcFault<TrapLevelZero>::vals = 208 {"trap_level_zero", 0x05F, 202, {H, H, SH}}; --- 26 unchanged lines hidden (view full) --- 235 SparcFault<CpuMondo>::vals = 236 {"cpu_mondo", 0x07C, 1608, {P, P, SH}}; 237 238template<> SparcFaultBase::FaultVals 239 SparcFault<DevMondo>::vals = 240 {"dev_mondo", 0x07D, 1611, {P, P, SH}}; 241 242template<> SparcFaultBase::FaultVals | 201 202template<> SparcFaultBase::FaultVals 203 SparcFault<HstickMatch>::vals = 204 {"hstick_match", 0x05E, 1601, {H, H, H}}; 205 206template<> SparcFaultBase::FaultVals 207 SparcFault<TrapLevelZero>::vals = 208 {"trap_level_zero", 0x05F, 202, {H, H, SH}}; --- 26 unchanged lines hidden (view full) --- 235 SparcFault<CpuMondo>::vals = 236 {"cpu_mondo", 0x07C, 1608, {P, P, SH}}; 237 238template<> SparcFaultBase::FaultVals 239 SparcFault<DevMondo>::vals = 240 {"dev_mondo", 0x07D, 1611, {P, P, SH}}; 241 242template<> SparcFaultBase::FaultVals |
243 SparcFault<ResumeableError>::vals = | 243 SparcFault |
244 {"resume_error", 0x07E, 3330, {P, P, SH}}; 245 246template<> SparcFaultBase::FaultVals 247 SparcFault<SpillNNormal>::vals = 248 {"spill_n_normal", 0x080, 900, {P, P, H}}; 249 250template<> SparcFaultBase::FaultVals 251 SparcFault<SpillNOther>::vals = --- 85 unchanged lines hidden (view full) --- 337 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 338 339 //TT = trap type; 340 tc->setMiscReg(MISCREG_TT, tt); 341 342 //Update GL 343 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); 344 | 244 {"resume_error", 0x07E, 3330, {P, P, SH}}; 245 246template<> SparcFaultBase::FaultVals 247 SparcFault<SpillNNormal>::vals = 248 {"spill_n_normal", 0x080, 900, {P, P, H}}; 249 250template<> SparcFaultBase::FaultVals 251 SparcFault<SpillNOther>::vals = --- 85 unchanged lines hidden (view full) --- 337 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 338 339 //TT = trap type; 340 tc->setMiscReg(MISCREG_TT, tt); 341 342 //Update GL 343 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); 344 |
345 //set PSTATE.mm to 00 346 //set PSTATE.pef to 1 347 PSTATE |= (1 << 4); 348 //set PSTATE.am to 0 349 PSTATE &= ~(1 << 3); 350/* //set PSTATE.priv to 0 351 PSTATE &= ~(1 << 2);*/ 352 //set PSTATE.ie to 0 353 //PSTATE.priv is set to 1 here. The manual says it should be 0, but 354 //Legion sets it to 1. 355 PSTATE |= (1 << 2); 356 //set PSTATE.cle to 0 357 PSTATE &= ~(1 << 9); 358 //PSTATE.tle is unchanged 359 //XXX Where is the tct bit? 360 //set PSTATE.tct to 0 | 345 PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit 346 PSTATE |= (1 << 4); //set PSTATE.pef to 1 |
361 tc->setMiscReg(MISCREG_PSTATE, PSTATE); 362 363 //set HPSTATE.red to 1 364 HPSTATE |= (1 << 5); 365 //set HPSTATE.hpriv to 1 366 HPSTATE |= (1 << 2); 367 //set HPSTATE.ibe to 0 368 HPSTATE &= ~(1 << 10); --- 66 unchanged lines hidden (view full) --- 435 436 //set HTSTATE.hpstate to hpstate 437 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 438 439 //TT = trap type; 440 tc->setMiscReg(MISCREG_TT, tt); 441 442 //Update the global register level | 347 tc->setMiscReg(MISCREG_PSTATE, PSTATE); 348 349 //set HPSTATE.red to 1 350 HPSTATE |= (1 << 5); 351 //set HPSTATE.hpriv to 1 352 HPSTATE |= (1 << 2); 353 //set HPSTATE.ibe to 0 354 HPSTATE &= ~(1 << 10); --- 66 unchanged lines hidden (view full) --- 421 422 //set HTSTATE.hpstate to hpstate 423 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 424 425 //TT = trap type; 426 tc->setMiscReg(MISCREG_TT, tt); 427 428 //Update the global register level |
443 if(!gotoHpriv) | 429 if (!gotoHpriv) |
444 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL)); 445 else 446 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); 447 448 //PSTATE.mm is unchanged | 430 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL)); 431 else 432 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); 433 434 //PSTATE.mm is unchanged |
449 //PSTATE.pef = whether or not an fpu is present 450 //XXX We'll say there's one present, even though there aren't 451 //implementations for a decent number of the instructions 452 PSTATE |= (1 << 4); 453 //PSTATE.am = 0 454 PSTATE &= ~(1 << 3); 455 if(!gotoHpriv) 456 { 457 //PSTATE.priv = 1 458 PSTATE |= (1 << 2); 459 //PSTATE.cle = PSTATE.tle 460 replaceBits(PSTATE, 9, 9, PSTATE >> 8); 461 } 462 else 463 { 464 //PSTATE.priv = 0 465 //PSTATE.priv is set to 1 here. The manual says it should be 0, but 466 //Legion sets it to 1. 467 PSTATE |= (1 << 2); 468 //PSTATE.cle = 0 469 PSTATE &= ~(1 << 9); 470 } 471 //PSTATE.ie = 0 472 PSTATE &= ~(1 << 1); | 435 PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present 436 PSTATE &= ~(1 << 3); //PSTATE.am = 0 437 PSTATE &= ~(1 << 1); //PSTATE.ie = 0 |
473 //PSTATE.tle is unchanged 474 //PSTATE.tct = 0 | 438 //PSTATE.tle is unchanged 439 //PSTATE.tct = 0 |
475 //XXX Where exactly is this field? 476 tc->setMiscReg(MISCREG_PSTATE, PSTATE); | |
477 | 440 |
478 if(gotoHpriv) | 441 if (gotoHpriv) |
479 { | 442 { |
480 //HPSTATE.red = 0 481 HPSTATE &= ~(1 << 5); 482 //HPSTATE.hpriv = 1 483 HPSTATE |= (1 << 2); 484 //HPSTATE.ibe = 0 485 HPSTATE &= ~(1 << 10); | 443 PSTATE &= ~(1 << 9); // PSTATE.cle = 0 444 //The manual says PSTATE.priv should be 0, but Legion leaves it alone 445 HPSTATE &= ~(1 << 5); //HPSTATE.red = 0 446 HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1 447 HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0 |
486 //HPSTATE.tlz is unchanged 487 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); | 448 //HPSTATE.tlz is unchanged 449 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); |
450 } else { // we are going to priv 451 PSTATE |= (1 << 2); //PSTATE.priv = 1 452 replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle |
|
488 } | 453 } |
454 tc->setMiscReg(MISCREG_PSTATE, PSTATE); |
|
489 | 455 |
456 |
|
490 bool changedCWP = true; | 457 bool changedCWP = true; |
491 if(tt == 0x24) | 458 if (tt == 0x24) |
492 CWP++; | 459 CWP++; |
493 else if(0x80 <= tt && tt <= 0xbf) | 460 else if (0x80 <= tt && tt <= 0xbf) |
494 CWP += (CANSAVE + 2); | 461 CWP += (CANSAVE + 2); |
495 else if(0xc0 <= tt && tt <= 0xff) | 462 else if (0xc0 <= tt && tt <= 0xff) |
496 CWP--; 497 else 498 changedCWP = false; 499 | 463 CWP--; 464 else 465 changedCWP = false; 466 |
500 if(changedCWP) | 467 if (changedCWP) |
501 { 502 CWP = (CWP + NWindows) % NWindows; 503 tc->setMiscRegWithEffect(MISCREG_CWP, CWP); 504 } 505} 506 507void getREDVector(MiscReg TT, Addr & PC, Addr & NPC) 508{ --- 24 unchanged lines hidden (view full) --- 533void SparcFaultBase::invoke(ThreadContext * tc) 534{ 535 //panic("Invoking a second fault!\n"); 536 FaultBase::invoke(tc); 537 countStat()++; 538 539 //We can refer to this to see what the trap level -was-, but something 540 //in the middle could change it in the regfile out from under us. | 468 { 469 CWP = (CWP + NWindows) % NWindows; 470 tc->setMiscRegWithEffect(MISCREG_CWP, CWP); 471 } 472} 473 474void getREDVector(MiscReg TT, Addr & PC, Addr & NPC) 475{ --- 24 unchanged lines hidden (view full) --- 500void SparcFaultBase::invoke(ThreadContext * tc) 501{ 502 //panic("Invoking a second fault!\n"); 503 FaultBase::invoke(tc); 504 countStat()++; 505 506 //We can refer to this to see what the trap level -was-, but something 507 //in the middle could change it in the regfile out from under us. |
541 MiscReg TL = tc->readMiscReg(MISCREG_TL); 542 MiscReg TT = tc->readMiscReg(MISCREG_TT); 543 MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); 544 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); | 508 MiscReg tl = tc->readMiscReg(MISCREG_TL); 509 MiscReg tt = tc->readMiscReg(MISCREG_TT); 510 MiscReg pstate = tc->readMiscReg(MISCREG_PSTATE); 511 MiscReg hpstate = tc->readMiscReg(MISCREG_HPSTATE); |
545 546 Addr PC, NPC; 547 548 PrivilegeLevel current; | 512 513 Addr PC, NPC; 514 515 PrivilegeLevel current; |
549 if(HPSTATE & (1 << 2)) | 516 if (hpstate & HPSTATE::hpriv) |
550 current = Hyperprivileged; | 517 current = Hyperprivileged; |
551 else if(PSTATE & (1 << 2)) | 518 else if (pstate & PSTATE::priv) |
552 current = Privileged; 553 else 554 current = User; 555 556 PrivilegeLevel level = getNextLevel(current); 557 | 519 current = Privileged; 520 else 521 current = User; 522 523 PrivilegeLevel level = getNextLevel(current); 524 |
558 if(HPSTATE & (1 << 5) || TL == MaxTL - 1) { | 525 if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { |
559 getREDVector(5, PC, NPC); | 526 getREDVector(5, PC, NPC); |
560 doREDFault(tc, TT); | 527 doREDFault(tc, tt); |
561 //This changes the hpstate and pstate, so we need to make sure we 562 //save the old version on the trap stack in doREDFault. 563 enterREDState(tc); | 528 //This changes the hpstate and pstate, so we need to make sure we 529 //save the old version on the trap stack in doREDFault. 530 enterREDState(tc); |
564 } else if(TL == MaxTL) { | 531 } else if (tl == MaxTL) { |
565 panic("Should go to error state here.. crap\n"); 566 //Do error_state somehow? 567 //Probably inject a WDR fault using the interrupt mechanism. 568 //What should the PC and NPC be set to? | 532 panic("Should go to error state here.. crap\n"); 533 //Do error_state somehow? 534 //Probably inject a WDR fault using the interrupt mechanism. 535 //What should the PC and NPC be set to? |
569 } else if(TL > MaxPTL && level == Privileged) { | 536 } else if (tl > MaxPTL && level == Privileged) { |
570 //guest_watchdog fault 571 doNormalFault(tc, trapType(), true); 572 getHyperVector(tc, PC, NPC, 2); | 537 //guest_watchdog fault 538 doNormalFault(tc, trapType(), true); 539 getHyperVector(tc, PC, NPC, 2); |
573 } else if(level == Hyperprivileged || | 540 } else if (level == Hyperprivileged || |
574 level == Privileged && trapType() >= 384) { 575 doNormalFault(tc, trapType(), true); 576 getHyperVector(tc, PC, NPC, trapType()); 577 } else { 578 doNormalFault(tc, trapType(), false); | 541 level == Privileged && trapType() >= 384) { 542 doNormalFault(tc, trapType(), true); 543 getHyperVector(tc, PC, NPC, trapType()); 544 } else { 545 doNormalFault(tc, trapType(), false); |
579 getPrivVector(tc, PC, NPC, trapType(), TL+1); | 546 getPrivVector(tc, PC, NPC, trapType(), tl+1); |
580 } 581 582 tc->setPC(PC); 583 tc->setNextPC(NPC); 584 tc->setNextNPC(NPC + sizeof(MachInst)); 585} 586 587void PowerOnReset::invoke(ThreadContext * tc) --- 120 unchanged lines hidden --- | 547 } 548 549 tc->setPC(PC); 550 tc->setNextPC(NPC); 551 tc->setNextNPC(NPC + sizeof(MachInst)); 552} 553 554void PowerOnReset::invoke(ThreadContext * tc) --- 120 unchanged lines hidden --- |