faults.cc (2800:18a615ca6e19) faults.cc (3415:72c48f292f6a)
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
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
32#include "arch/sparc/faults.hh"
34#include "arch/sparc/faults.hh"
33#include "cpu/thread_context.hh"
34#include "cpu/base.hh"
35#include "arch/sparc/isa_traits.hh"
36#include "arch/sparc/process.hh"
37#include "base/bitfield.hh"
35#include "base/trace.hh"
38#include "base/trace.hh"
39#include "cpu/base.hh"
40#include "cpu/thread_context.hh"
36#if !FULL_SYSTEM
41#if !FULL_SYSTEM
37#include "sim/process.hh"
38#include "mem/page_table.hh"
42#include "mem/page_table.hh"
43#include "sim/process.hh"
39#endif
40
44#endif
45
46using namespace std;
47
41namespace SparcISA
42{
43
44FaultName InternalProcessorError::_name = "intprocerr";
45TrapType InternalProcessorError::_trapType = 0x029;
46FaultPriority InternalProcessorError::_priority = 4;
47FaultStat InternalProcessorError::_count;
48

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

224
225#if !FULL_SYSTEM
226FaultName PageTableFault::_name = "page_table_fault";
227TrapType PageTableFault::_trapType = 0x0000;
228FaultPriority PageTableFault::_priority = 0;
229FaultStat PageTableFault::_count;
230#endif
231
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
232#if FULL_SYSTEM
233
234void SparcFault::invoke(ThreadContext * tc)
235{
236 FaultBase::invoke(tc);
237 countStat()++;
238
239 //Use the SPARC trap state machine

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

258
259#if !FULL_SYSTEM
260
261void TrapInstruction::invoke(ThreadContext * tc)
262{
263 // Should be handled in ISA.
264}
265
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
266void PageTableFault::invoke(ThreadContext *tc)
267{
268 Process *p = tc->getProcessPtr();
269
270 // address is higher than the stack region or in the current stack region
271 if (vaddr > p->stack_base || vaddr > p->stack_min)
272 FaultBase::invoke(tc);
273
274 // We've accessed the next page
275 if (vaddr > p->stack_min - PageBytes) {
276 p->stack_min -= PageBytes;
277 if (p->stack_base - p->stack_min > 8*1024*1024)
278 fatal("Over max stack size for one thread\n");
279 p->pTable->allocate(p->stack_min, PageBytes);
280 warn("Increasing stack size by one page.");
281 } else {
282 FaultBase::invoke(tc);
283 }
284}
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
285#endif
286
287} // namespace SparcISA
288
452#endif
453
454} // namespace SparcISA
455