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