faults.cc (7720:65d338a8dba4) | faults.cc (7741:340b6f01d69b) |
---|---|
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; --- 258 unchanged lines hidden (view full) --- 267 SparcFault<TrapInstruction>::vals = 268 {"trap_instruction", 0x100, 1602, {P, P, H}}; 269 270/** 271 * This causes the thread context to enter RED state. This causes the side 272 * effects which go with entering RED state because of a trap. 273 */ 274 | 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; --- 258 unchanged lines hidden (view full) --- 267 SparcFault<TrapInstruction>::vals = 268 {"trap_instruction", 0x100, 1602, {P, P, H}}; 269 270/** 271 * This causes the thread context to enter RED state. This causes the side 272 * effects which go with entering RED state because of a trap. 273 */ 274 |
275void enterREDState(ThreadContext *tc) | 275void 276enterREDState(ThreadContext *tc) |
276{ 277 //@todo Disable the mmu? 278 //@todo Disable watchpoints? 279 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); | 277{ 278 //@todo Disable the mmu? 279 //@todo Disable watchpoints? 280 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); |
280 //HPSTATE.red = 1 | 281 // HPSTATE.red = 1 |
281 HPSTATE |= (1 << 5); | 282 HPSTATE |= (1 << 5); |
282 //HPSTATE.hpriv = 1 | 283 // HPSTATE.hpriv = 1 |
283 HPSTATE |= (1 << 2); 284 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); | 284 HPSTATE |= (1 << 2); 285 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); |
285 //PSTATE.priv is set to 1 here. The manual says it should be 0, but 286 //Legion sets it to 1. | 286 // PSTATE.priv is set to 1 here. The manual says it should be 0, but 287 // Legion sets it to 1. |
287 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 288 PSTATE |= (1 << 2); 289 tc->setMiscReg(MISCREG_PSTATE, PSTATE); 290} 291 292/** 293 * This sets everything up for a RED state trap except for actually jumping to 294 * the handler. 295 */ 296 | 288 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 289 PSTATE |= (1 << 2); 290 tc->setMiscReg(MISCREG_PSTATE, PSTATE); 291} 292 293/** 294 * This sets everything up for a RED state trap except for actually jumping to 295 * the handler. 296 */ 297 |
297void doREDFault(ThreadContext *tc, TrapType tt) | 298void 299doREDFault(ThreadContext *tc, TrapType tt) |
298{ 299 MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 300 MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 301 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 302 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); | 300{ 301 MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 302 MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 303 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 304 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); |
303 //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR); | |
304 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 305 MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 306 MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); | 305 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 306 MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 307 MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); |
307 //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE); | |
308 MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3); 309 MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 310 PCState pc = tc->pcState(); 311 312 TL++; 313 314 Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64); 315 | 308 MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3); 309 MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 310 PCState pc = tc->pcState(); 311 312 TL++; 313 314 Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64); 315 |
316 //set TSTATE.gl to gl | 316 // set TSTATE.gl to gl |
317 replaceBits(TSTATE, 42, 40, GL); | 317 replaceBits(TSTATE, 42, 40, GL); |
318 //set TSTATE.ccr to ccr | 318 // set TSTATE.ccr to ccr |
319 replaceBits(TSTATE, 39, 32, CCR); | 319 replaceBits(TSTATE, 39, 32, CCR); |
320 //set TSTATE.asi to asi | 320 // set TSTATE.asi to asi |
321 replaceBits(TSTATE, 31, 24, ASI); | 321 replaceBits(TSTATE, 31, 24, ASI); |
322 //set TSTATE.pstate to pstate | 322 // set TSTATE.pstate to pstate |
323 replaceBits(TSTATE, 20, 8, PSTATE); | 323 replaceBits(TSTATE, 20, 8, PSTATE); |
324 //set TSTATE.cwp to cwp | 324 // set TSTATE.cwp to cwp |
325 replaceBits(TSTATE, 4, 0, CWP); 326 | 325 replaceBits(TSTATE, 4, 0, CWP); 326 |
327 //Write back TSTATE | 327 // Write back TSTATE |
328 tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 329 | 328 tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 329 |
330 //set TPC to PC | 330 // set TPC to PC |
331 tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask); | 331 tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask); |
332 //set TNPC to NPC | 332 // set TNPC to NPC |
333 tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); 334 | 333 tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); 334 |
335 //set HTSTATE.hpstate to hpstate | 335 // set HTSTATE.hpstate to hpstate |
336 tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); 337 | 336 tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); 337 |
338 //TT = trap type; | 338 // TT = trap type; |
339 tc->setMiscRegNoEffect(MISCREG_TT, tt); 340 | 339 tc->setMiscRegNoEffect(MISCREG_TT, tt); 340 |
341 //Update GL | 341 // Update GL |
342 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); 343 344 PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit | 342 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); 343 344 PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit |
345 PSTATE |= (1 << 4); //set PSTATE.pef to 1 | 345 PSTATE |= (1 << 4); // set PSTATE.pef to 1 |
346 tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); 347 | 346 tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); 347 |
348 //set HPSTATE.red to 1 | 348 // set HPSTATE.red to 1 |
349 HPSTATE |= (1 << 5); | 349 HPSTATE |= (1 << 5); |
350 //set HPSTATE.hpriv to 1 | 350 // set HPSTATE.hpriv to 1 |
351 HPSTATE |= (1 << 2); | 351 HPSTATE |= (1 << 2); |
352 //set HPSTATE.ibe to 0 | 352 // set HPSTATE.ibe to 0 |
353 HPSTATE &= ~(1 << 10); | 353 HPSTATE &= ~(1 << 10); |
354 //set HPSTATE.tlz to 0 | 354 // set HPSTATE.tlz to 0 |
355 HPSTATE &= ~(1 << 0); 356 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 357 358 bool changedCWP = true; | 355 HPSTATE &= ~(1 << 0); 356 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 357 358 bool changedCWP = true; |
359 if(tt == 0x24) | 359 if (tt == 0x24) |
360 CWP++; | 360 CWP++; |
361 else if(0x80 <= tt && tt <= 0xbf) | 361 else if (0x80 <= tt && tt <= 0xbf) |
362 CWP += (CANSAVE + 2); | 362 CWP += (CANSAVE + 2); |
363 else if(0xc0 <= tt && tt <= 0xff) | 363 else if (0xc0 <= tt && tt <= 0xff) |
364 CWP--; 365 else 366 changedCWP = false; 367 | 364 CWP--; 365 else 366 changedCWP = false; 367 |
368 if(changedCWP) 369 { | 368 if (changedCWP) { |
370 CWP = (CWP + NWindows) % NWindows; 371 tc->setMiscReg(MISCREG_CWP, CWP); 372 } 373} 374 375/** 376 * This sets everything up for a normal trap except for actually jumping to 377 * the handler. 378 */ 379 | 369 CWP = (CWP + NWindows) % NWindows; 370 tc->setMiscReg(MISCREG_CWP, CWP); 371 } 372} 373 374/** 375 * This sets everything up for a normal trap except for actually jumping to 376 * the handler. 377 */ 378 |
380void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) | 379void 380doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) |
381{ 382 MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 383 MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 384 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 385 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); | 381{ 382 MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); 383 MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); 384 MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); 385 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); |
386 //MiscReg CCR = tc->readMiscRegNoEffect(MISCREG_CCR); | |
387 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 388 MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 389 MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); | 386 MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); 387 MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); 388 MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); |
390 //MiscReg CANSAVE = tc->readMiscRegNoEffect(MISCREG_CANSAVE); | |
391 MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); 392 MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 393 PCState pc = tc->pcState(); 394 | 389 MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3); 390 MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL); 391 PCState pc = tc->pcState(); 392 |
395 //Increment the trap level | 393 // Increment the trap level |
396 TL++; 397 tc->setMiscRegNoEffect(MISCREG_TL, TL); 398 399 Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64); 400 | 394 TL++; 395 tc->setMiscRegNoEffect(MISCREG_TL, TL); 396 397 Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64); 398 |
401 //Save off state | 399 // Save off state |
402 | 400 |
403 //set TSTATE.gl to gl | 401 // set TSTATE.gl to gl |
404 replaceBits(TSTATE, 42, 40, GL); | 402 replaceBits(TSTATE, 42, 40, GL); |
405 //set TSTATE.ccr to ccr | 403 // set TSTATE.ccr to ccr |
406 replaceBits(TSTATE, 39, 32, CCR); | 404 replaceBits(TSTATE, 39, 32, CCR); |
407 //set TSTATE.asi to asi | 405 // set TSTATE.asi to asi |
408 replaceBits(TSTATE, 31, 24, ASI); | 406 replaceBits(TSTATE, 31, 24, ASI); |
409 //set TSTATE.pstate to pstate | 407 // set TSTATE.pstate to pstate |
410 replaceBits(TSTATE, 20, 8, PSTATE); | 408 replaceBits(TSTATE, 20, 8, PSTATE); |
411 //set TSTATE.cwp to cwp | 409 // set TSTATE.cwp to cwp |
412 replaceBits(TSTATE, 4, 0, CWP); 413 | 410 replaceBits(TSTATE, 4, 0, CWP); 411 |
414 //Write back TSTATE | 412 // Write back TSTATE |
415 tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 416 | 413 tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE); 414 |
417 //set TPC to PC | 415 // set TPC to PC |
418 tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask); | 416 tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask); |
419 //set TNPC to NPC | 417 // set TNPC to NPC |
420 tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); 421 | 418 tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); 419 |
422 //set HTSTATE.hpstate to hpstate | 420 // set HTSTATE.hpstate to hpstate |
423 tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); 424 | 421 tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); 422 |
425 //TT = trap type; | 423 // TT = trap type; |
426 tc->setMiscRegNoEffect(MISCREG_TT, tt); 427 | 424 tc->setMiscRegNoEffect(MISCREG_TT, tt); 425 |
428 //Update the global register level | 426 // Update the global register level |
429 if (!gotoHpriv) | 427 if (!gotoHpriv) |
430 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxPGL)); | 428 tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxPGL)); |
431 else | 429 else |
432 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); | 430 tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL)); |
433 | 431 |
434 //PSTATE.mm is unchanged 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 438 //PSTATE.tle is unchanged 439 //PSTATE.tct = 0 | 432 // PSTATE.mm is unchanged 433 PSTATE |= (1 << 4); // PSTATE.pef = whether or not an fpu is present 434 PSTATE &= ~(1 << 3); // PSTATE.am = 0 435 PSTATE &= ~(1 << 1); // PSTATE.ie = 0 436 // PSTATE.tle is unchanged 437 // PSTATE.tct = 0 |
440 | 438 |
441 if (gotoHpriv) 442 { | 439 if (gotoHpriv) { |
443 PSTATE &= ~(1 << 9); // PSTATE.cle = 0 | 440 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 448 //HPSTATE.tlz is unchanged | 441 // The manual says PSTATE.priv should be 0, but Legion leaves it alone 442 HPSTATE &= ~(1 << 5); // HPSTATE.red = 0 443 HPSTATE |= (1 << 2); // HPSTATE.hpriv = 1 444 HPSTATE &= ~(1 << 10); // HPSTATE.ibe = 0 445 // HPSTATE.tlz is unchanged |
449 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 450 } else { // we are going to priv | 446 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 447 } else { // we are going to priv |
451 PSTATE |= (1 << 2); //PSTATE.priv = 1 452 replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle | 448 PSTATE |= (1 << 2); // PSTATE.priv = 1 449 replaceBits(PSTATE, 9, 9, PSTATE >> 8); // PSTATE.cle = PSTATE.tle |
453 } 454 tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); 455 456 457 bool changedCWP = true; 458 if (tt == 0x24) 459 CWP++; 460 else if (0x80 <= tt && tt <= 0xbf) 461 CWP += (CANSAVE + 2); 462 else if (0xc0 <= tt && tt <= 0xff) 463 CWP--; 464 else 465 changedCWP = false; 466 | 450 } 451 tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); 452 453 454 bool changedCWP = true; 455 if (tt == 0x24) 456 CWP++; 457 else if (0x80 <= tt && tt <= 0xbf) 458 CWP += (CANSAVE + 2); 459 else if (0xc0 <= tt && tt <= 0xff) 460 CWP--; 461 else 462 changedCWP = false; 463 |
467 if (changedCWP) 468 { | 464 if (changedCWP) { |
469 CWP = (CWP + NWindows) % NWindows; 470 tc->setMiscReg(MISCREG_CWP, CWP); 471 } 472} 473 | 465 CWP = (CWP + NWindows) % NWindows; 466 tc->setMiscReg(MISCREG_CWP, CWP); 467 } 468} 469 |
474void getREDVector(MiscReg TT, Addr &PC, Addr &NPC) | 470void 471getREDVector(MiscReg TT, Addr &PC, Addr &NPC) |
475{ 476 //XXX The following constant might belong in a header file. 477 const Addr RSTVAddr = 0xFFF0000000ULL; 478 PC = RSTVAddr | ((TT << 5) & 0xFF); 479 NPC = PC + sizeof(MachInst); 480} 481 | 472{ 473 //XXX The following constant might belong in a header file. 474 const Addr RSTVAddr = 0xFFF0000000ULL; 475 PC = RSTVAddr | ((TT << 5) & 0xFF); 476 NPC = PC + sizeof(MachInst); 477} 478 |
482void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT) | 479void 480getHyperVector(ThreadContext * tc, Addr &PC, Addr &NPC, MiscReg TT) |
483{ 484 Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA); 485 PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); 486 NPC = PC + sizeof(MachInst); 487} 488 | 481{ 482 Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA); 483 PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); 484 NPC = PC + sizeof(MachInst); 485} 486 |
489void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) | 487void 488getPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, MiscReg TT, MiscReg TL) |
490{ 491 Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA); 492 PC = (TBA & ~mask(15)) | 493 (TL > 1 ? (1 << 14) : 0) | 494 ((TT << 5) & mask(14)); 495 NPC = PC + sizeof(MachInst); 496} 497 498#if FULL_SYSTEM 499 | 489{ 490 Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA); 491 PC = (TBA & ~mask(15)) | 492 (TL > 1 ? (1 << 14) : 0) | 493 ((TT << 5) & mask(14)); 494 NPC = PC + sizeof(MachInst); 495} 496 497#if FULL_SYSTEM 498 |
500void SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst) | 499void 500SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst) |
501{ | 501{ |
502 //panic("Invoking a second fault!\n"); | |
503 FaultBase::invoke(tc); 504 countStat()++; 505 | 502 FaultBase::invoke(tc); 503 countStat()++; 504 |
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. | 505 // We can refer to this to see what the trap level -was-, but something 506 // in the middle could change it in the regfile out from under us. |
508 MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL); 509 MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT); 510 MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 511 MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 512 513 Addr PC, NPC; 514 515 PrivilegeLevel current; --- 4 unchanged lines hidden (view full) --- 520 else 521 current = User; 522 523 PrivilegeLevel level = getNextLevel(current); 524 525 if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { 526 getREDVector(5, PC, NPC); 527 doREDFault(tc, tt); | 507 MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL); 508 MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT); 509 MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); 510 MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); 511 512 Addr PC, NPC; 513 514 PrivilegeLevel current; --- 4 unchanged lines hidden (view full) --- 519 else 520 current = User; 521 522 PrivilegeLevel level = getNextLevel(current); 523 524 if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { 525 getREDVector(5, PC, NPC); 526 doREDFault(tc, tt); |
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. | 527 // This changes the hpstate and pstate, so we need to make sure we 528 // save the old version on the trap stack in doREDFault. |
530 enterREDState(tc); 531 } else if (tl == MaxTL) { 532 panic("Should go to error state here.. crap\n"); | 529 enterREDState(tc); 530 } else if (tl == MaxTL) { 531 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? | 532 // Do error_state somehow? 533 // Probably inject a WDR fault using the interrupt mechanism. 534 // What should the PC and NPC be set to? |
536 } else if (tl > MaxPTL && level == Privileged) { | 535 } else if (tl > MaxPTL && level == Privileged) { |
537 //guest_watchdog fault | 536 // guest_watchdog fault |
538 doNormalFault(tc, trapType(), true); 539 getHyperVector(tc, PC, NPC, 2); 540 } else if (level == Hyperprivileged || 541 (level == Privileged && trapType() >= 384)) { 542 doNormalFault(tc, trapType(), true); 543 getHyperVector(tc, PC, NPC, trapType()); 544 } else { 545 doNormalFault(tc, trapType(), false); | 537 doNormalFault(tc, trapType(), true); 538 getHyperVector(tc, PC, NPC, 2); 539 } else if (level == Hyperprivileged || 540 (level == Privileged && trapType() >= 384)) { 541 doNormalFault(tc, trapType(), true); 542 getHyperVector(tc, PC, NPC, trapType()); 543 } else { 544 doNormalFault(tc, trapType(), false); |
546 getPrivVector(tc, PC, NPC, trapType(), tl+1); | 545 getPrivVector(tc, PC, NPC, trapType(), tl + 1); |
547 } 548 549 PCState pc; 550 pc.pc(PC); 551 pc.npc(NPC); 552 pc.nnpc(NPC + sizeof(MachInst)); 553 pc.upc(0); 554 pc.nupc(1); 555 tc->pcState(pc); 556} 557 | 546 } 547 548 PCState pc; 549 pc.pc(PC); 550 pc.npc(NPC); 551 pc.nnpc(NPC + sizeof(MachInst)); 552 pc.upc(0); 553 pc.nupc(1); 554 tc->pcState(pc); 555} 556 |
558void PowerOnReset::invoke(ThreadContext * tc, StaticInstPtr inst) | 557void 558PowerOnReset::invoke(ThreadContext *tc, StaticInstPtr inst) |
559{ | 559{ |
560 //For SPARC, when a system is first started, there is a power 561 //on reset Trap which sets the processor into the following state. 562 //Bits that aren't set aren't defined on startup. | 560 // For SPARC, when a system is first started, there is a power 561 // on reset Trap which sets the processor into the following state. 562 // Bits that aren't set aren't defined on startup. |
563 564 tc->setMiscRegNoEffect(MISCREG_TL, MaxTL); 565 tc->setMiscRegNoEffect(MISCREG_TT, trapType()); 566 tc->setMiscReg(MISCREG_GL, MaxGL); 567 | 563 564 tc->setMiscRegNoEffect(MISCREG_TL, MaxTL); 565 tc->setMiscRegNoEffect(MISCREG_TT, trapType()); 566 tc->setMiscReg(MISCREG_GL, MaxGL); 567 |
568 //Turn on pef and priv, set everything else to 0 | 568 // Turn on pef and priv, set everything else to 0 |
569 tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2)); 570 | 569 tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2)); 570 |
571 //Turn on red and hpriv, set everything else to 0 | 571 // Turn on red and hpriv, set everything else to 0 |
572 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); | 572 MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); |
573 //HPSTATE.red = 1 | 573 // HPSTATE.red = 1 |
574 HPSTATE |= (1 << 5); | 574 HPSTATE |= (1 << 5); |
575 //HPSTATE.hpriv = 1 | 575 // HPSTATE.hpriv = 1 |
576 HPSTATE |= (1 << 2); | 576 HPSTATE |= (1 << 2); |
577 //HPSTATE.ibe = 0 | 577 // HPSTATE.ibe = 0 |
578 HPSTATE &= ~(1 << 10); | 578 HPSTATE &= ~(1 << 10); |
579 //HPSTATE.tlz = 0 | 579 // HPSTATE.tlz = 0 |
580 HPSTATE &= ~(1 << 0); 581 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 582 | 580 HPSTATE &= ~(1 << 0); 581 tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); 582 |
583 //The tick register is unreadable by nonprivileged software | 583 // The tick register is unreadable by nonprivileged software |
584 tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63); 585 | 584 tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63); 585 |
586 //Enter RED state. We do this last so that the actual state preserved in 587 //the trap stack is the state from before this fault. | 586 // Enter RED state. We do this last so that the actual state preserved in 587 // the trap stack is the state from before this fault. |
588 enterREDState(tc); 589 590 Addr PC, NPC; 591 getREDVector(trapType(), PC, NPC); 592 593 PCState pc; 594 pc.pc(PC); 595 pc.npc(NPC); 596 pc.nnpc(NPC + sizeof(MachInst)); 597 pc.upc(0); 598 pc.nupc(1); 599 tc->pcState(pc); 600 | 588 enterREDState(tc); 589 590 Addr PC, NPC; 591 getREDVector(trapType(), PC, NPC); 592 593 PCState pc; 594 pc.pc(PC); 595 pc.npc(NPC); 596 pc.nnpc(NPC + sizeof(MachInst)); 597 pc.upc(0); 598 pc.nupc(1); 599 tc->pcState(pc); 600 |
601 //These registers are specified as "undefined" after a POR, and they 602 //should have reasonable values after the miscregfile is reset | 601 // These registers are specified as "undefined" after a POR, and they 602 // should have reasonable values after the miscregfile is reset |
603 /* 604 // Clear all the soft interrupt bits 605 softint = 0; 606 // disable timer compare interrupts, reset tick_cmpr 607 tc->setMiscRegNoEffect(MISCREG_ 608 tick_cmprFields.int_dis = 1; 609 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing | 603 /* 604 // Clear all the soft interrupt bits 605 softint = 0; 606 // disable timer compare interrupts, reset tick_cmpr 607 tc->setMiscRegNoEffect(MISCREG_ 608 tick_cmprFields.int_dis = 1; 609 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing |
610 stickFields.npt = 1; //The TICK register is unreadable by by !priv | 610 stickFields.npt = 1; // The TICK register is unreadable by by !priv |
611 stick_cmprFields.int_dis = 1; // disable timer compare interrupts 612 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 613 614 tt[tl] = _trapType; 615 616 hintp = 0; // no interrupts pending 617 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts 618 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 619 */ 620} 621 622#else // !FULL_SYSTEM 623 | 611 stick_cmprFields.int_dis = 1; // disable timer compare interrupts 612 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 613 614 tt[tl] = _trapType; 615 616 hintp = 0; // no interrupts pending 617 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts 618 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing 619 */ 620} 621 622#else // !FULL_SYSTEM 623 |
624void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, 625 StaticInstPtr inst) | 624void 625FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst) |
626{ 627 Process *p = tc->getProcessPtr(); 628 TlbEntry entry; 629 bool success = p->pTable->lookup(vaddr, entry); | 626{ 627 Process *p = tc->getProcessPtr(); 628 TlbEntry entry; 629 bool success = p->pTable->lookup(vaddr, entry); |
630 if(!success) { | 630 if (!success) { |
631 panic("Tried to execute unmapped address %#x.\n", vaddr); 632 } else { 633 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 634 tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/, 635 p->M5_pid /*context id*/, false, entry.pte); 636 } 637} 638 | 631 panic("Tried to execute unmapped address %#x.\n", vaddr); 632 } else { 633 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 634 tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/, 635 p->M5_pid /*context id*/, false, entry.pte); 636 } 637} 638 |
639void FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst) | 639void 640FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst) |
640{ 641 Process *p = tc->getProcessPtr(); 642 TlbEntry entry; 643 bool success = p->pTable->lookup(vaddr, entry); | 641{ 642 Process *p = tc->getProcessPtr(); 643 TlbEntry entry; 644 bool success = p->pTable->lookup(vaddr, entry); |
644 if(!success) { | 645 if (!success) { |
645 p->checkAndAllocNextPage(vaddr); 646 success = p->pTable->lookup(vaddr, entry); 647 } | 646 p->checkAndAllocNextPage(vaddr); 647 success = p->pTable->lookup(vaddr, entry); 648 } |
648 if(!success) { | 649 if (!success) { |
649 panic("Tried to access unmapped address %#x.\n", vaddr); 650 } else { 651 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 652 tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/, 653 p->M5_pid /*context id*/, false, entry.pte); 654 } 655} 656 | 650 panic("Tried to access unmapped address %#x.\n", vaddr); 651 } else { 652 Addr alignedVaddr = p->pTable->pageAlign(vaddr); 653 tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/, 654 p->M5_pid /*context id*/, false, entry.pte); 655 } 656} 657 |
657void SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst) | 658void 659SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst) |
658{ 659 doNormalFault(tc, trapType(), false); 660 661 Process *p = tc->getProcessPtr(); 662 663 //XXX This will only work in faults from a SparcLiveProcess 664 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 665 assert(lp); 666 | 660{ 661 doNormalFault(tc, trapType(), false); 662 663 Process *p = tc->getProcessPtr(); 664 665 //XXX This will only work in faults from a SparcLiveProcess 666 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 667 assert(lp); 668 |
667 //Then adjust the PC and NPC | 669 // Then adjust the PC and NPC |
668 tc->pcState(lp->readSpillStart()); 669} 670 | 670 tc->pcState(lp->readSpillStart()); 671} 672 |
671void FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst) | 673void 674FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst) |
672{ 673 doNormalFault(tc, trapType(), false); 674 | 675{ 676 doNormalFault(tc, trapType(), false); 677 |
675 Process * p = tc->getProcessPtr(); | 678 Process *p = tc->getProcessPtr(); |
676 677 //XXX This will only work in faults from a SparcLiveProcess 678 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 679 assert(lp); 680 | 679 680 //XXX This will only work in faults from a SparcLiveProcess 681 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 682 assert(lp); 683 |
681 //Then adjust the PC and NPC | 684 // Then adjust the PC and NPC |
682 tc->pcState(lp->readFillStart()); 683} 684 | 685 tc->pcState(lp->readFillStart()); 686} 687 |
685void TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst) | 688void 689TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst) |
686{ | 690{ |
687 //In SE, this mechanism is how the process requests a service from the 688 //operating system. We'll get the process object from the thread context 689 //and let it service the request. | 691 // In SE, this mechanism is how the process requests a service from the 692 // operating system. We'll get the process object from the thread context 693 // and let it service the request. |
690 691 Process *p = tc->getProcessPtr(); 692 693 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 694 assert(lp); 695 696 lp->handleTrap(_n, tc); 697 | 694 695 Process *p = tc->getProcessPtr(); 696 697 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 698 assert(lp); 699 700 lp->handleTrap(_n, tc); 701 |
698 //We need to explicitly advance the pc, since that's not done for us 699 //on a faulting instruction | 702 // We need to explicitly advance the pc, since that's not done for us 703 // on a faulting instruction |
700 PCState pc = tc->pcState(); 701 pc.advance(); 702 tc->pcState(pc); 703} 704 705#endif 706 707} // namespace SparcISA 708 | 704 PCState pc = tc->pcState(); 705 pc.advance(); 706 tc->pcState(pc); 707} 708 709#endif 710 711} // namespace SparcISA 712 |