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; --- 268 unchanged lines hidden (view full) --- 277 * This causes the thread context to enter RED state. This causes the side 278 * effects which go with entering RED state because of a trap. 279 */ 280 281void enterREDState(ThreadContext *tc) 282{ 283 //@todo Disable the mmu? 284 //@todo Disable watchpoints? |
285 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); |
286 //HPSTATE.red = 1 287 HPSTATE |= (1 << 5); 288 //HPSTATE.hpriv = 1 289 HPSTATE |= (1 << 2); |
290 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); |
291 //PSTATE.priv is set to 1 here. The manual says it should be 0, but 292 //Legion sets it to 1. |
293 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); |
294 PSTATE |= (1 << 2); |
295 tc->setMiscReg(MISCREG_PSTATE, PSTATE); |
296} 297 298/** 299 * This sets everything up for a RED state trap except for actually jumping to 300 * the handler. 301 */ 302 303void doREDFault(ThreadContext *tc, TrapType tt) 304{ |
305 MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 306 MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 307 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 308 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 309 //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR); |
310 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); |
311 MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 312 MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); 313 //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE); 314 MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3); 315 MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); |
316 MiscReg PC = tc->readPC(); 317 MiscReg NPC = tc->readNextPC(); 318 319 TL++; 320 321 if (bits(PSTATE, 3,3)) { 322 PC &= mask(32); 323 NPC &= mask(32); --- 6 unchanged lines hidden (view full) --- 330 //set TSTATE.asi to asi 331 replaceBits(TSTATE, 31, 24, ASI); 332 //set TSTATE.pstate to pstate 333 replaceBits(TSTATE, 20, 8, PSTATE); 334 //set TSTATE.cwp to cwp 335 replaceBits(TSTATE, 4, 0, CWP); 336 337 //Write back TSTATE |
338 tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); |
339 340 //set TPC to PC |
341 tc->setMiscRegNoEffect(MISCREG_TPC, PC); |
342 //set TNPC to NPC |
343 tc->setMiscRegNoEffect(MISCREG_TNPC, NPC); |
344 345 //set HTSTATE.hpstate to hpstate |
346 tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); |
347 348 //TT = trap type; |
349 tc->setMiscRegNoEffect(MISCREG_TT, tt); |
350 351 //Update GL |
352 tc->setMiscReg(MISCREG_GL, min |
353 354 PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit 355 PSTATE |= (1 << 4); //set PSTATE.pef to 1 |
356 tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); |
357 358 //set HPSTATE.red to 1 359 HPSTATE |= (1 << 5); 360 //set HPSTATE.hpriv to 1 361 HPSTATE |= (1 << 2); 362 //set HPSTATE.ibe to 0 363 HPSTATE &= ~(1 << 10); 364 //set HPSTATE.tlz to 0 365 HPSTATE &= ~(1 << 0); |
366 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); |
367 368 bool changedCWP = true; 369 if(tt == 0x24) 370 CWP++; 371 else if(0x80 <= tt && tt <= 0xbf) 372 CWP += (CANSAVE + 2); 373 else if(0xc0 <= tt && tt <= 0xff) 374 CWP--; 375 else 376 changedCWP = false; 377 378 if(changedCWP) 379 { 380 CWP = (CWP + NWindows) % NWindows; |
381 tc->setMiscReg(MISCREG_CWP, CWP); |
382 } 383} 384 385/** 386 * This sets everything up for a normal trap except for actually jumping to 387 * the handler. 388 */ 389 390void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) 391{ |
392 MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 393 MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 394 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 395 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 396 //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR); |
397 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); |
398 MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 399 MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); 400 //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE); |
401 MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); |
402 MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); |
403 MiscReg PC = tc->readPC(); 404 MiscReg NPC = tc->readNextPC(); 405 406 if (bits(PSTATE, 3,3)) { 407 PC &= mask(32); 408 NPC &= mask(32); 409 } 410 411 //Increment the trap level 412 TL++; |
413 tc->setMiscRegNoEffect(MISCREG_TL, TL); |
414 415 //Save off state 416 417 //set TSTATE.gl to gl 418 replaceBits(TSTATE, 42, 40, GL); 419 //set TSTATE.ccr to ccr 420 replaceBits(TSTATE, 39, 32, CCR); 421 //set TSTATE.asi to asi 422 replaceBits(TSTATE, 31, 24, ASI); 423 //set TSTATE.pstate to pstate 424 replaceBits(TSTATE, 20, 8, PSTATE); 425 //set TSTATE.cwp to cwp 426 replaceBits(TSTATE, 4, 0, CWP); 427 428 //Write back TSTATE |
429 tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); |
430 431 //set TPC to PC |
432 tc->setMiscRegNoEffect(MISCREG_TPC, PC); |
433 //set TNPC to NPC |
434 tc->setMiscRegNoEffect(MISCREG_TNPC, NPC); |
435 436 //set HTSTATE.hpstate to hpstate |
437 tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); |
438 439 //TT = trap type; |
440 tc->setMiscRegNoEffect(MISCREG_TT, tt); |
441 442 //Update the global register level 443 if (!gotoHpriv) |
444 tc->setMiscReg(MISCREG_GL, min |
445 else |
446 tc->setMiscReg(MISCREG_GL, min |
447 448 //PSTATE.mm is unchanged 449 PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present 450 PSTATE &= ~(1 << 3); //PSTATE.am = 0 451 PSTATE &= ~(1 << 1); //PSTATE.ie = 0 452 //PSTATE.tle is unchanged 453 //PSTATE.tct = 0 454 455 if (gotoHpriv) 456 { 457 PSTATE &= ~(1 << 9); // PSTATE.cle = 0 458 //The manual says PSTATE.priv should be 0, but Legion leaves it alone 459 HPSTATE &= ~(1 << 5); //HPSTATE.red = 0 460 HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1 461 HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0 462 //HPSTATE.tlz is unchanged |
463 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); |
464 } else { // we are going to priv 465 PSTATE |= (1 << 2); //PSTATE.priv = 1 466 replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle 467 } |
468 tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); |
469 470 471 bool changedCWP = true; 472 if (tt == 0x24) 473 CWP++; 474 else if (0x80 <= tt && tt <= 0xbf) 475 CWP += (CANSAVE + 2); 476 else if (0xc0 <= tt && tt <= 0xff) 477 CWP--; 478 else 479 changedCWP = false; 480 481 if (changedCWP) 482 { 483 CWP = (CWP + NWindows) % NWindows; |
484 tc->setMiscReg(MISCREG_CWP, CWP); |
485 } 486} 487 488void getREDVector(MiscReg TT, Addr & PC, Addr & NPC) 489{ 490 //XXX The following constant might belong in a header file. 491 const Addr RSTVAddr = 0xFFF0000000ULL; 492 PC = RSTVAddr | ((TT << 5) & 0xFF); 493 NPC = PC + sizeof(MachInst); 494} 495 496void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT) 497{ |
498 Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA); |
499 PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); 500 NPC = PC + sizeof(MachInst); 501} 502 503void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) 504{ |
505 Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA); |
506 PC = (TBA & ~mask(15)) | 507 (TL > 1 ? (1 << 14) : 0) | 508 ((TT << 5) & mask(14)); 509 NPC = PC + sizeof(MachInst); 510} 511 512#if FULL_SYSTEM 513 514void SparcFaultBase::invoke(ThreadContext * tc) 515{ 516 //panic("Invoking a second fault!\n"); 517 FaultBase::invoke(tc); 518 countStat()++; 519 520 //We can refer to this to see what the trap level -was-, but something 521 //in the middle could change it in the regfile out from under us. |
522 MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL); 523 MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT); 524 MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 525 MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); |
526 527 Addr PC, NPC; 528 529 PrivilegeLevel current; 530 if (hpstate & HPSTATE::hpriv) 531 current = Hyperprivileged; 532 else if (pstate & PSTATE::priv) 533 current = Privileged; --- 32 unchanged lines hidden (view full) --- 566} 567 568void PowerOnReset::invoke(ThreadContext * tc) 569{ 570 //For SPARC, when a system is first started, there is a power 571 //on reset Trap which sets the processor into the following state. 572 //Bits that aren't set aren't defined on startup. 573 |
574 tc->setMiscRegNoEffect(MISCREG_TL, MaxTL); 575 tc->setMiscRegNoEffect(MISCREG_TT, trapType()); 576 tc->setMiscReg(MISCREG_GL, MaxGL); |
577 578 //Turn on pef and priv, set everything else to 0 |
579 tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2)); |
580 581 //Turn on red and hpriv, set everything else to 0 |
582 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); |
583 //HPSTATE.red = 1 584 HPSTATE |= (1 << 5); 585 //HPSTATE.hpriv = 1 586 HPSTATE |= (1 << 2); 587 //HPSTATE.ibe = 0 588 HPSTATE &= ~(1 << 10); 589 //HPSTATE.tlz = 0 590 HPSTATE &= ~(1 << 0); |
591 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); |
592 593 //The tick register is unreadable by nonprivileged software |
594 tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63); |
595 596 //Enter RED state. We do this last so that the actual state preserved in 597 //the trap stack is the state from before this fault. 598 enterREDState(tc); 599 600 Addr PC, NPC; 601 getREDVector(trapType(), PC, NPC); 602 tc->setPC(PC); 603 tc->setNextPC(NPC); 604 tc->setNextNPC(NPC + sizeof(MachInst)); 605 606 //These registers are specified as "undefined" after a POR, and they 607 //should have reasonable values after the miscregfile is reset 608 /* 609 // Clear all the soft interrupt bits 610 softint = 0; 611 // disable timer compare interrupts, reset tick_cmpr |
612 tc->setMiscRegNoEffect(MISCREG_ |
613 tick_cmprFields.int_dis = 1; 614 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 615 stickFields.npt = 1; //The TICK register is unreadable by by !priv 616 stick_cmprFields.int_dis = 1; // disable timer compare interrupts 617 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 618 619 tt[tl] = _trapType; 620 --- 88 unchanged lines hidden --- |