faults.cc (3928:9486450f013f) faults.cc (3949:b6664282d899)
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", 0x040, 0, {P, P, SH}};
200 {"interrupt_level_n", 0x041, 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::vals =
243 SparcFault<ResumeableError>::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 =

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

297 */
298
299void doREDFault(ThreadContext *tc, TrapType tt)
300{
301 MiscReg TL = tc->readMiscReg(MISCREG_TL);
302 MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
303 MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
304 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
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 =

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

297 */
298
299void doREDFault(ThreadContext *tc, TrapType tt)
300{
301 MiscReg TL = tc->readMiscReg(MISCREG_TL);
302 MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
303 MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
304 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
305 MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
305 //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
306 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
306 MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
307 MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
307 MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
308 MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
308 MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
309 //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
310 MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3);
309 MiscReg GL = tc->readMiscReg(MISCREG_GL);
310 MiscReg PC = tc->readPC();
311 MiscReg NPC = tc->readNextPC();
312
313 TL++;
314
311 MiscReg GL = tc->readMiscReg(MISCREG_GL);
312 MiscReg PC = tc->readPC();
313 MiscReg NPC = tc->readNextPC();
314
315 TL++;
316
315 if (bits(PSTATE, 3,3)) {
316 PC &= mask(32);
317 NPC &= mask(32);
318 }
319
320 //set TSTATE.gl to gl
321 replaceBits(TSTATE, 42, 40, GL);
322 //set TSTATE.ccr to ccr
323 replaceBits(TSTATE, 39, 32, CCR);
324 //set TSTATE.asi to asi
325 replaceBits(TSTATE, 31, 24, ASI);
326 //set TSTATE.pstate to pstate
327 replaceBits(TSTATE, 20, 8, PSTATE);

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

340 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
341
342 //TT = trap type;
343 tc->setMiscReg(MISCREG_TT, tt);
344
345 //Update GL
346 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
347
317 //set TSTATE.gl to gl
318 replaceBits(TSTATE, 42, 40, GL);
319 //set TSTATE.ccr to ccr
320 replaceBits(TSTATE, 39, 32, CCR);
321 //set TSTATE.asi to asi
322 replaceBits(TSTATE, 31, 24, ASI);
323 //set TSTATE.pstate to pstate
324 replaceBits(TSTATE, 20, 8, PSTATE);

--- 12 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
348 PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
349 PSTATE |= (1 << 4); //set PSTATE.pef to 1
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
350 tc->setMiscReg(MISCREG_PSTATE, PSTATE);
351
352 //set HPSTATE.red to 1
353 HPSTATE |= (1 << 5);
354 //set HPSTATE.hpriv to 1
355 HPSTATE |= (1 << 2);
356 //set HPSTATE.ibe to 0
357 HPSTATE &= ~(1 << 10);

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

382 */
383
384void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
385{
386 MiscReg TL = tc->readMiscReg(MISCREG_TL);
387 MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
388 MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
389 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
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);

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

393 */
394
395void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
396{
397 MiscReg TL = tc->readMiscReg(MISCREG_TL);
398 MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
399 MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
400 MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
390 MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
401 //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
402 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
391 MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
392 MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
403 MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
404 MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
393 MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
405 //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
406 MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
394 MiscReg GL = tc->readMiscReg(MISCREG_GL);
395 MiscReg PC = tc->readPC();
396 MiscReg NPC = tc->readNextPC();
397
407 MiscReg GL = tc->readMiscReg(MISCREG_GL);
408 MiscReg PC = tc->readPC();
409 MiscReg NPC = tc->readNextPC();
410
398 if (bits(PSTATE, 3,3)) {
399 PC &= mask(32);
400 NPC &= mask(32);
401 }
402
403 //Increment the trap level
404 TL++;
405 tc->setMiscReg(MISCREG_TL, TL);
406
407 //Save off state
408
409 //set TSTATE.gl to gl
410 replaceBits(TSTATE, 42, 40, GL);

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

427
428 //set HTSTATE.hpstate to hpstate
429 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
430
431 //TT = trap type;
432 tc->setMiscReg(MISCREG_TT, tt);
433
434 //Update the global register level
411 //Increment the trap level
412 TL++;
413 tc->setMiscReg(MISCREG_TL, TL);
414
415 //Save off state
416
417 //set TSTATE.gl to gl
418 replaceBits(TSTATE, 42, 40, GL);

--- 16 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
435 if (!gotoHpriv)
443 if(!gotoHpriv)
436 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
437 else
438 tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
439
440 //PSTATE.mm is unchanged
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
441 PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present
442 PSTATE &= ~(1 << 3); //PSTATE.am = 0
443 PSTATE &= ~(1 << 1); //PSTATE.ie = 0
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);
444 //PSTATE.tle is unchanged
445 //PSTATE.tct = 0
473 //PSTATE.tle is unchanged
474 //PSTATE.tct = 0
475 //XXX Where exactly is this field?
476 tc->setMiscReg(MISCREG_PSTATE, PSTATE);
446
477
447 if (gotoHpriv)
478 if(gotoHpriv)
448 {
479 {
449 PSTATE &= ~(1 << 9); // PSTATE.cle = 0
450 //The manual says PSTATE.priv should be 0, but Legion leaves it alone
451 HPSTATE &= ~(1 << 5); //HPSTATE.red = 0
452 HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1
453 HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0
480 //HPSTATE.red = 0
481 HPSTATE &= ~(1 << 5);
482 //HPSTATE.hpriv = 1
483 HPSTATE |= (1 << 2);
484 //HPSTATE.ibe = 0
485 HPSTATE &= ~(1 << 10);
454 //HPSTATE.tlz is unchanged
455 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
486 //HPSTATE.tlz is unchanged
487 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
456 } else { // we are going to priv
457 PSTATE |= (1 << 2); //PSTATE.priv = 1
458 replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle
459 }
488 }
460 tc->setMiscReg(MISCREG_PSTATE, PSTATE);
461
489
462
463 bool changedCWP = true;
490 bool changedCWP = true;
464 if (tt == 0x24)
491 if(tt == 0x24)
465 CWP++;
492 CWP++;
466 else if (0x80 <= tt && tt <= 0xbf)
493 else if(0x80 <= tt && tt <= 0xbf)
467 CWP += (CANSAVE + 2);
494 CWP += (CANSAVE + 2);
468 else if (0xc0 <= tt && tt <= 0xff)
495 else if(0xc0 <= tt && tt <= 0xff)
469 CWP--;
470 else
471 changedCWP = false;
472
496 CWP--;
497 else
498 changedCWP = false;
499
473 if (changedCWP)
500 if(changedCWP)
474 {
475 CWP = (CWP + NWindows) % NWindows;
476 tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
477 }
478}
479
480void getREDVector(MiscReg TT, Addr & PC, Addr & NPC)
481{

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

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

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

651 tc->setNextPC(fillStart + sizeof(MachInst));
652 tc->setNextNPC(fillStart + 2*sizeof(MachInst));
653}
654
655void PageTableFault::invoke(ThreadContext *tc)
656{
657 Process *p = tc->getProcessPtr();
658
580 }
581
582 tc->setPC(PC);
583 tc->setNextPC(NPC);
584 tc->setNextNPC(NPC + sizeof(MachInst));
585}
586
587void PowerOnReset::invoke(ThreadContext * tc)

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

678 tc->setNextPC(fillStart + sizeof(MachInst));
679 tc->setNextNPC(fillStart + 2*sizeof(MachInst));
680}
681
682void PageTableFault::invoke(ThreadContext *tc)
683{
684 Process *p = tc->getProcessPtr();
685
659 // address is higher than the stack region or in the current stack region
660 if (vaddr > p->stack_base || vaddr > p->stack_min)
661 FaultBase::invoke(tc);
662
663 // We've accessed the next page
664 if (vaddr > p->stack_min - PageBytes) {
686 // We've accessed the next page of the stack, so extend the stack
687 // to cover it.
688 if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes)
689 {
665 p->stack_min -= PageBytes;
690 p->stack_min -= PageBytes;
666 if (p->stack_base - p->stack_min > 8*1024*1024)
691 if(p->stack_base - p->stack_min > 8*1024*1024)
667 fatal("Over max stack size for one thread\n");
668 p->pTable->allocate(p->stack_min, PageBytes);
669 warn("Increasing stack size by one page.");
692 fatal("Over max stack size for one thread\n");
693 p->pTable->allocate(p->stack_min, PageBytes);
694 warn("Increasing stack size by one page.");
670 } else {
671 FaultBase::invoke(tc);
672 }
695 }
696 // Otherwise, we have an unexpected page fault. Report that fact,
697 // and what address was accessed to cause the fault.
698 else
699 {
700 panic("Page table fault when accessing virtual address %#x\n", vaddr);
701 }
673}
674
675#endif
676
677} // namespace SparcISA
678
702}
703
704#endif
705
706} // namespace SparcISA
707