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

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