faults.cc (3890:5530906ab80a) faults.cc (3893:e2a358430839)
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;

--- 226 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
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;

--- 226 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::vals =
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 =

--- 179 unchanged lines hidden (view full) ---

431
432 //set HTSTATE.hpstate to hpstate
433 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
434
435 //TT = trap type;
436 tc->setMiscReg(MISCREG_TT, tt);
437
438 //Update the global register level
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 =

--- 179 unchanged lines hidden (view full) ---

431
432 //set HTSTATE.hpstate to hpstate
433 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
434
435 //TT = trap type;
436 tc->setMiscReg(MISCREG_TT, tt);
437
438 //Update the global register level
439 if(!gotoHpriv)
439 if (!gotoHpriv)
440 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
441 else
442 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
443
444 //PSTATE.mm is unchanged
445 //PSTATE.pef = whether or not an fpu is present
446 //XXX We'll say there's one present, even though there aren't
447 //implementations for a decent number of the instructions
448 PSTATE |= (1 << 4);
449 //PSTATE.am = 0
450 PSTATE &= ~(1 << 3);
440 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
441 else
442 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
443
444 //PSTATE.mm is unchanged
445 //PSTATE.pef = whether or not an fpu is present
446 //XXX We'll say there's one present, even though there aren't
447 //implementations for a decent number of the instructions
448 PSTATE |= (1 << 4);
449 //PSTATE.am = 0
450 PSTATE &= ~(1 << 3);
451 if(!gotoHpriv)
451 if (!gotoHpriv)
452 {
453 //PSTATE.priv = 1
454 PSTATE |= (1 << 2);
455 //PSTATE.cle = PSTATE.tle
456 replaceBits(PSTATE, 9, 9, PSTATE >> 8);
457 }
458 else
459 {

--- 6 unchanged lines hidden (view full) ---

466 }
467 //PSTATE.ie = 0
468 PSTATE &= ~(1 << 1);
469 //PSTATE.tle is unchanged
470 //PSTATE.tct = 0
471 //XXX Where exactly is this field?
472 tc->setMiscReg(MISCREG_PSTATE, PSTATE);
473
452 {
453 //PSTATE.priv = 1
454 PSTATE |= (1 << 2);
455 //PSTATE.cle = PSTATE.tle
456 replaceBits(PSTATE, 9, 9, PSTATE >> 8);
457 }
458 else
459 {

--- 6 unchanged lines hidden (view full) ---

466 }
467 //PSTATE.ie = 0
468 PSTATE &= ~(1 << 1);
469 //PSTATE.tle is unchanged
470 //PSTATE.tct = 0
471 //XXX Where exactly is this field?
472 tc->setMiscReg(MISCREG_PSTATE, PSTATE);
473
474 if(gotoHpriv)
474 if (gotoHpriv)
475 {
476 //HPSTATE.red = 0
477 HPSTATE &= ~(1 << 5);
478 //HPSTATE.hpriv = 1
479 HPSTATE |= (1 << 2);
480 //HPSTATE.ibe = 0
481 HPSTATE &= ~(1 << 10);
482 //HPSTATE.tlz is unchanged
483 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
484 }
485
486 bool changedCWP = true;
475 {
476 //HPSTATE.red = 0
477 HPSTATE &= ~(1 << 5);
478 //HPSTATE.hpriv = 1
479 HPSTATE |= (1 << 2);
480 //HPSTATE.ibe = 0
481 HPSTATE &= ~(1 << 10);
482 //HPSTATE.tlz is unchanged
483 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
484 }
485
486 bool changedCWP = true;
487 if(tt == 0x24)
487 if (tt == 0x24)
488 CWP++;
488 CWP++;
489 else if(0x80 <= tt && tt <= 0xbf)
489 else if (0x80 <= tt && tt <= 0xbf)
490 CWP += (CANSAVE + 2);
490 CWP += (CANSAVE + 2);
491 else if(0xc0 <= tt && tt <= 0xff)
491 else if (0xc0 <= tt && tt <= 0xff)
492 CWP--;
493 else
494 changedCWP = false;
495
492 CWP--;
493 else
494 changedCWP = false;
495
496 if(changedCWP)
496 if (changedCWP)
497 {
498 CWP = (CWP + NWindows) % NWindows;
499 tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
500 }
501}
502
503void getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
504{

--- 24 unchanged lines hidden (view full) ---

529void SparcFaultBase::invoke(ThreadContext * tc)
530{
531 //panic("Invoking a second fault!\n");
532 FaultBase::invoke(tc);
533 countStat()++;
534
535 //We can refer to this to see what the trap level -was-, but something
536 //in the middle could change it in the regfile out from under us.
497 {
498 CWP = (CWP + NWindows) % NWindows;
499 tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
500 }
501}
502
503void getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
504{

--- 24 unchanged lines hidden (view full) ---

529void SparcFaultBase::invoke(ThreadContext * tc)
530{
531 //panic("Invoking a second fault!\n");
532 FaultBase::invoke(tc);
533 countStat()++;
534
535 //We can refer to this to see what the trap level -was-, but something
536 //in the middle could change it in the regfile out from under us.
537 MiscReg TL = tc->readMiscReg(MISCREG_TL);
538 MiscReg TT = tc->readMiscReg(MISCREG_TT);
539 MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
540 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
537 MiscReg tl = tc->readMiscReg(MISCREG_TL);
538 MiscReg tt = tc->readMiscReg(MISCREG_TT);
539 MiscReg pstate = tc->readMiscReg(MISCREG_PSTATE);
540 MiscReg hpstate = tc->readMiscReg(MISCREG_HPSTATE);
541
542 Addr PC, NPC;
543
544 PrivilegeLevel current;
541
542 Addr PC, NPC;
543
544 PrivilegeLevel current;
545 if(HPSTATE & (1 << 2))
545 if (hpstate & HPSTATE::hpriv)
546 current = Hyperprivileged;
546 current = Hyperprivileged;
547 else if(PSTATE & (1 << 2))
547 else if (pstate & PSTATE::priv)
548 current = Privileged;
549 else
550 current = User;
551
552 PrivilegeLevel level = getNextLevel(current);
553
548 current = Privileged;
549 else
550 current = User;
551
552 PrivilegeLevel level = getNextLevel(current);
553
554 if(HPSTATE & (1 << 5) || TL == MaxTL - 1) {
554 if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) {
555 getREDVector(5, PC, NPC);
555 getREDVector(5, PC, NPC);
556 doREDFault(tc, TT);
556 doREDFault(tc, tt);
557 //This changes the hpstate and pstate, so we need to make sure we
558 //save the old version on the trap stack in doREDFault.
559 enterREDState(tc);
557 //This changes the hpstate and pstate, so we need to make sure we
558 //save the old version on the trap stack in doREDFault.
559 enterREDState(tc);
560 } else if(TL == MaxTL) {
560 } else if (tl == MaxTL) {
561 panic("Should go to error state here.. crap\n");
562 //Do error_state somehow?
563 //Probably inject a WDR fault using the interrupt mechanism.
564 //What should the PC and NPC be set to?
561 panic("Should go to error state here.. crap\n");
562 //Do error_state somehow?
563 //Probably inject a WDR fault using the interrupt mechanism.
564 //What should the PC and NPC be set to?
565 } else if(TL > MaxPTL && level == Privileged) {
565 } else if (tl > MaxPTL && level == Privileged) {
566 //guest_watchdog fault
567 doNormalFault(tc, trapType(), true);
568 getHyperVector(tc, PC, NPC, 2);
566 //guest_watchdog fault
567 doNormalFault(tc, trapType(), true);
568 getHyperVector(tc, PC, NPC, 2);
569 } else if(level == Hyperprivileged ||
569 } else if (level == Hyperprivileged ||
570 level == Privileged && trapType() >= 384) {
571 doNormalFault(tc, trapType(), true);
572 getHyperVector(tc, PC, NPC, trapType());
573 } else {
574 doNormalFault(tc, trapType(), false);
570 level == Privileged && trapType() >= 384) {
571 doNormalFault(tc, trapType(), true);
572 getHyperVector(tc, PC, NPC, trapType());
573 } else {
574 doNormalFault(tc, trapType(), false);
575 getPrivVector(tc, PC, NPC, trapType(), TL+1);
575 getPrivVector(tc, PC, NPC, trapType(), tl+1);
576 }
577
578 tc->setPC(PC);
579 tc->setNextPC(NPC);
580 tc->setNextNPC(NPC + sizeof(MachInst));
581}
582
583void PowerOnReset::invoke(ThreadContext * tc)

--- 118 unchanged lines hidden ---
576 }
577
578 tc->setPC(PC);
579 tc->setNextPC(NPC);
580 tc->setNextNPC(NPC + sizeof(MachInst));
581}
582
583void PowerOnReset::invoke(ThreadContext * tc)

--- 118 unchanged lines hidden ---