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; --- 15 unchanged lines hidden (view full) --- 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Gabe Black 29 * Kevin Lim 30 */ 31 |
32#include <algorithm> 33 |
34#include "arch/sparc/faults.hh" |
35#include "arch/sparc/isa_traits.hh" 36#include "arch/sparc/process.hh" 37#include "base/bitfield.hh" |
38#include "base/trace.hh" |
39#include "cpu/base.hh" 40#include "cpu/thread_context.hh" |
41#if !FULL_SYSTEM |
42#include "mem/page_table.hh" |
43#include "sim/process.hh" |
44#endif 45 |
46using namespace std; 47 |
48namespace SparcISA 49{ 50 51FaultName InternalProcessorError::_name = "intprocerr"; 52TrapType InternalProcessorError::_trapType = 0x029; 53FaultPriority InternalProcessorError::_priority = 4; 54FaultStat InternalProcessorError::_count; 55 --- 175 unchanged lines hidden (view full) --- 231 232#if !FULL_SYSTEM 233FaultName PageTableFault::_name = "page_table_fault"; 234TrapType PageTableFault::_trapType = 0x0000; 235FaultPriority PageTableFault::_priority = 0; 236FaultStat PageTableFault::_count; 237#endif 238 |
239/** 240 * This sets everything up for a normal trap except for actually jumping to 241 * the handler. It will need to be expanded to include the state machine in 242 * the manual. Right now it assumes that traps will always be to the 243 * privileged level. 244 */ 245 246void doNormalFault(ThreadContext *tc, TrapType tt) 247{ 248 uint64_t TL = tc->readMiscReg(MISCREG_TL); 249 uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE); 250 uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE); 251 uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); 252 uint64_t CCR = tc->readMiscReg(MISCREG_CCR); 253 uint64_t ASI = tc->readMiscReg(MISCREG_ASI); 254 uint64_t CWP = tc->readMiscReg(MISCREG_CWP); 255 uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); 256 uint64_t GL = tc->readMiscReg(MISCREG_GL); 257 uint64_t PC = tc->readPC(); 258 uint64_t NPC = tc->readNextPC(); 259 260 //Increment the trap level 261 TL++; 262 tc->setMiscReg(MISCREG_TL, TL); 263 264 //Save off state 265 266 //set TSTATE.gl to gl 267 replaceBits(TSTATE, 42, 40, GL); 268 //set TSTATE.ccr to ccr 269 replaceBits(TSTATE, 39, 32, CCR); 270 //set TSTATE.asi to asi 271 replaceBits(TSTATE, 31, 24, ASI); 272 //set TSTATE.pstate to pstate 273 replaceBits(TSTATE, 20, 8, PSTATE); 274 //set TSTATE.cwp to cwp 275 replaceBits(TSTATE, 4, 0, CWP); 276 277 //Write back TSTATE 278 tc->setMiscReg(MISCREG_TSTATE, TSTATE); 279 280 //set TPC to PC 281 tc->setMiscReg(MISCREG_TPC, PC); 282 //set TNPC to NPC 283 tc->setMiscReg(MISCREG_TNPC, NPC); 284 285 //set HTSTATE.hpstate to hpstate 286 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); 287 288 //TT = trap type; 289 tc->setMiscReg(MISCREG_TT, tt); 290 291 //Update the global register level 292 if(1/*We're delivering the trap in priveleged mode*/) 293 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL)); 294 else 295 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxPGL)); 296 297 //PSTATE.mm is unchanged 298 //PSTATE.pef = whether or not an fpu is present 299 //XXX We'll say there's one present, even though there aren't 300 //implementations for a decent number of the instructions 301 PSTATE |= (1 << 4); 302 //PSTATE.am = 0 303 PSTATE &= ~(1 << 3); 304 if(1/*We're delivering the trap in priveleged mode*/) 305 { 306 //PSTATE.priv = 1 307 PSTATE |= (1 << 2); 308 //PSTATE.cle = PSTATE.tle 309 replaceBits(PSTATE, 9, 9, PSTATE >> 8); 310 } 311 else 312 { 313 //PSTATE.priv = 0 314 PSTATE &= ~(1 << 2); 315 //PSTATE.cle = 0 316 PSTATE &= ~(1 << 9); 317 } 318 //PSTATE.ie = 0 319 PSTATE &= ~(1 << 1); 320 //PSTATE.tle is unchanged 321 //PSTATE.tct = 0 322 //XXX Where exactly is this field? 323 tc->setMiscReg(MISCREG_PSTATE, PSTATE); 324 325 if(0/*We're delivering the trap in hyperprivileged mode*/) 326 { 327 //HPSTATE.red = 0 328 HPSTATE &= ~(1 << 5); 329 //HPSTATE.hpriv = 1 330 HPSTATE |= (1 << 2); 331 //HPSTATE.ibe = 0 332 HPSTATE &= ~(1 << 10); 333 //HPSTATE.tlz is unchanged 334 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); 335 } 336 337 bool changedCWP = true; 338 if(tt == 0x24) 339 { 340 warn("Incrementing the CWP by 1\n"); 341 CWP++; 342 } 343 else if(0x80 <= tt && tt <= 0xbf) 344 { 345 warn("Incrementing the CWP by %d\n", CANSAVE + 2); 346 CWP += (CANSAVE + 2); 347 } 348 else if(0xc0 <= tt && tt <= 0xff) 349 { 350 warn("Decrementing the CWP by 1\n"); 351 CWP--; 352 } 353 else 354 changedCWP = false; 355 if(changedCWP) 356 { 357 CWP = (CWP + NWindows) % NWindows; 358 tc->setMiscRegWithEffect(MISCREG_CWP, CWP); 359 } 360} 361 |
362#if FULL_SYSTEM 363 364void SparcFault::invoke(ThreadContext * tc) 365{ 366 FaultBase::invoke(tc); 367 countStat()++; 368 369 //Use the SPARC trap state machine --- 18 unchanged lines hidden (view full) --- 388 389#if !FULL_SYSTEM 390 391void TrapInstruction::invoke(ThreadContext * tc) 392{ 393 // Should be handled in ISA. 394} 395 |
396void SpillNNormal::invoke(ThreadContext *tc) 397{ 398 warn("I'm in a spill trap\n"); 399 doNormalFault(tc, trapType()); 400 401 Process *p = tc->getProcessPtr(); 402 403 //This will only work in faults from a SparcLiveProcess 404 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 405 assert(lp); 406 407 //Then adjust the PC and NPC 408 Addr spillStart = lp->readSpillStart(); 409 tc->setPC(spillStart); 410 tc->setNextPC(spillStart + sizeof(MachInst)); 411 tc->setNextNPC(spillStart + 2*sizeof(MachInst)); 412} 413 414void FillNNormal::invoke(ThreadContext *tc) 415{ 416 warn("I'm in a fill trap\n"); 417 doNormalFault(tc, trapType()); 418 419 Process * p = tc->getProcessPtr(); 420 421 //This will only work in faults from a SparcLiveProcess 422 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); 423 assert(lp); 424 425 //The adjust the PC and NPC 426 Addr fillStart = lp->readFillStart(); 427 tc->setPC(fillStart); 428 tc->setNextPC(fillStart + sizeof(MachInst)); 429 tc->setNextNPC(fillStart + 2*sizeof(MachInst)); 430} 431 |
432void PageTableFault::invoke(ThreadContext *tc) 433{ 434 Process *p = tc->getProcessPtr(); 435 436 // address is higher than the stack region or in the current stack region 437 if (vaddr > p->stack_base || vaddr > p->stack_min) 438 FaultBase::invoke(tc); 439 440 // We've accessed the next page 441 if (vaddr > p->stack_min - PageBytes) { 442 p->stack_min -= PageBytes; 443 if (p->stack_base - p->stack_min > 8*1024*1024) 444 fatal("Over max stack size for one thread\n"); 445 p->pTable->allocate(p->stack_min, PageBytes); 446 warn("Increasing stack size by one page."); 447 } else { 448 FaultBase::invoke(tc); 449 } 450} |
451 |
452#endif 453 454} // namespace SparcISA 455 |