faults.cc (3572:aa8751395277) faults.cc (3573:2038a2e549b5)
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;

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

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"
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;

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

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"
36#include "base/bitfield.hh"
37#include "base/trace.hh"
37#include "base/bitfield.hh"
38#include "base/trace.hh"
38#include "config/full_system.hh"
39#include "cpu/base.hh"
40#include "cpu/thread_context.hh"
41#if !FULL_SYSTEM
39#include "cpu/base.hh"
40#include "cpu/thread_context.hh"
41#if !FULL_SYSTEM
42#include "arch/sparc/process.hh"
43#include "mem/page_table.hh"
44#include "sim/process.hh"
45#endif
46
47using namespace std;
48
49namespace SparcISA
50{
51
42#include "mem/page_table.hh"
43#include "sim/process.hh"
44#endif
45
46using namespace std;
47
48namespace SparcISA
49{
50
52FaultName InternalProcessorError::_name = "intprocerr";
53TrapType InternalProcessorError::_trapType = 0x029;
54FaultPriority InternalProcessorError::_priority = 4;
55FaultStat InternalProcessorError::_count;
51template<> SparcFaultBase::FaultVals
52 SparcFault<InternalProcessorError>::vals = {"intprocerr", 0x029, 4};
56
53
57FaultName MemAddressNotAligned::_name = "unalign";
58TrapType MemAddressNotAligned::_trapType = 0x034;
59FaultPriority MemAddressNotAligned::_priority = 10;
60FaultStat MemAddressNotAligned::_count;
54template<> SparcFaultBase::FaultVals
55 SparcFault<MemAddressNotAligned>::vals = {"unalign", 0x034, 10};
61
56
62FaultName PowerOnReset::_name = "pow_reset";
63TrapType PowerOnReset::_trapType = 0x001;
64FaultPriority PowerOnReset::_priority = 0;
65FaultStat PowerOnReset::_count;
57template<> SparcFaultBase::FaultVals
58 SparcFault<PowerOnReset>::vals = {"pow_reset", 0x001, 0};
66
59
67FaultName WatchDogReset::_name = "watch_dog_reset";
68TrapType WatchDogReset::_trapType = 0x002;
69FaultPriority WatchDogReset::_priority = 1;
70FaultStat WatchDogReset::_count;
60template<> SparcFaultBase::FaultVals
61 SparcFault<WatchDogReset>::vals = {"watch_dog_reset", 0x002, 1};
71
62
72FaultName ExternallyInitiatedReset::_name = "extern_reset";
73TrapType ExternallyInitiatedReset::_trapType = 0x003;
74FaultPriority ExternallyInitiatedReset::_priority = 1;
75FaultStat ExternallyInitiatedReset::_count;
63template<> SparcFaultBase::FaultVals
64 SparcFault<ExternallyInitiatedReset>::vals = {"extern_reset", 0x003, 1};
76
65
77FaultName SoftwareInitiatedReset::_name = "software_reset";
78TrapType SoftwareInitiatedReset::_trapType = 0x004;
79FaultPriority SoftwareInitiatedReset::_priority = 1;
80FaultStat SoftwareInitiatedReset::_count;
66template<> SparcFaultBase::FaultVals
67 SparcFault<SoftwareInitiatedReset>::vals = {"software_reset", 0x004, 1};
81
68
82FaultName REDStateException::_name = "red_counte";
83TrapType REDStateException::_trapType = 0x005;
84FaultPriority REDStateException::_priority = 1;
85FaultStat REDStateException::_count;
69template<> SparcFaultBase::FaultVals
70 SparcFault<REDStateException>::vals = {"red_counte", 0x005, 1};
86
71
87FaultName InstructionAccessException::_name = "inst_access";
88TrapType InstructionAccessException::_trapType = 0x008;
89FaultPriority InstructionAccessException::_priority = 5;
90FaultStat InstructionAccessException::_count;
72template<> SparcFaultBase::FaultVals
73 SparcFault<InstructionAccessException>::vals = {"inst_access", 0x008, 5};
91
74
92FaultName InstructionAccessMMUMiss::_name = "inst_mmu";
93TrapType InstructionAccessMMUMiss::_trapType = 0x009;
94FaultPriority InstructionAccessMMUMiss::_priority = 2;
95FaultStat InstructionAccessMMUMiss::_count;
75template<> SparcFaultBase::FaultVals
76 SparcFault<InstructionAccessMMUMiss>::vals = {"inst_mmu", 0x009, 2};
96
77
97FaultName InstructionAccessError::_name = "inst_error";
98TrapType InstructionAccessError::_trapType = 0x00A;
99FaultPriority InstructionAccessError::_priority = 3;
100FaultStat InstructionAccessError::_count;
78template<> SparcFaultBase::FaultVals
79 SparcFault<InstructionAccessError>::vals = {"inst_error", 0x00A, 3};
101
80
102FaultName IllegalInstruction::_name = "illegal_inst";
103TrapType IllegalInstruction::_trapType = 0x010;
104FaultPriority IllegalInstruction::_priority = 7;
105FaultStat IllegalInstruction::_count;
81template<> SparcFaultBase::FaultVals
82 SparcFault<IllegalInstruction>::vals = {"illegal_inst", 0x010, 7};
106
83
107FaultName PrivilegedOpcode::_name = "priv_opcode";
108TrapType PrivilegedOpcode::_trapType = 0x011;
109FaultPriority PrivilegedOpcode::_priority = 6;
110FaultStat PrivilegedOpcode::_count;
84template<> SparcFaultBase::FaultVals
85 SparcFault<PrivilegedOpcode>::vals = {"priv_opcode", 0x011, 6};
111
86
112FaultName UnimplementedLDD::_name = "unimp_ldd";
113TrapType UnimplementedLDD::_trapType = 0x012;
114FaultPriority UnimplementedLDD::_priority = 6;
115FaultStat UnimplementedLDD::_count;
87template<> SparcFaultBase::FaultVals
88 SparcFault<UnimplementedLDD>::vals = {"unimp_ldd", 0x012, 6};
116
89
117FaultName UnimplementedSTD::_name = "unimp_std";
118TrapType UnimplementedSTD::_trapType = 0x013;
119FaultPriority UnimplementedSTD::_priority = 6;
120FaultStat UnimplementedSTD::_count;
90template<> SparcFaultBase::FaultVals
91 SparcFault<UnimplementedSTD>::vals = {"unimp_std", 0x013, 6};
121
92
122FaultName FpDisabled::_name = "fp_disabled";
123TrapType FpDisabled::_trapType = 0x020;
124FaultPriority FpDisabled::_priority = 8;
125FaultStat FpDisabled::_count;
93template<> SparcFaultBase::FaultVals
94 SparcFault<FpDisabled>::vals = {"fp_disabled", 0x020, 8};
126
95
127FaultName FpExceptionIEEE754::_name = "fp_754";
128TrapType FpExceptionIEEE754::_trapType = 0x021;
129FaultPriority FpExceptionIEEE754::_priority = 11;
130FaultStat FpExceptionIEEE754::_count;
96template<> SparcFaultBase::FaultVals
97 SparcFault<FpExceptionIEEE754>::vals = {"fp_754", 0x021, 11};
131
98
132FaultName FpExceptionOther::_name = "fp_other";
133TrapType FpExceptionOther::_trapType = 0x022;
134FaultPriority FpExceptionOther::_priority = 11;
135FaultStat FpExceptionOther::_count;
99template<> SparcFaultBase::FaultVals
100 SparcFault<FpExceptionOther>::vals = {"fp_other", 0x022, 11};
136
101
137FaultName TagOverflow::_name = "tag_overflow";
138TrapType TagOverflow::_trapType = 0x023;
139FaultPriority TagOverflow::_priority = 14;
140FaultStat TagOverflow::_count;
102template<> SparcFaultBase::FaultVals
103 SparcFault<TagOverflow>::vals = {"tag_overflow", 0x023, 14};
141
104
142FaultName DivisionByZero::_name = "div_by_zero";
143TrapType DivisionByZero::_trapType = 0x028;
144FaultPriority DivisionByZero::_priority = 15;
145FaultStat DivisionByZero::_count;
105template<> SparcFaultBase::FaultVals
106 SparcFault<DivisionByZero>::vals = {"div_by_zero", 0x028, 15};
146
107
147FaultName DataAccessException::_name = "data_access";
148TrapType DataAccessException::_trapType = 0x030;
149FaultPriority DataAccessException::_priority = 12;
150FaultStat DataAccessException::_count;
108template<> SparcFaultBase::FaultVals
109 SparcFault<DataAccessException>::vals = {"data_access", 0x030, 12};
151
110
152FaultName DataAccessMMUMiss::_name = "data_mmu";
153TrapType DataAccessMMUMiss::_trapType = 0x031;
154FaultPriority DataAccessMMUMiss::_priority = 12;
155FaultStat DataAccessMMUMiss::_count;
111template<> SparcFaultBase::FaultVals
112 SparcFault<DataAccessMMUMiss>::vals = {"data_mmu", 0x031, 12};
156
113
157FaultName DataAccessError::_name = "data_error";
158TrapType DataAccessError::_trapType = 0x032;
159FaultPriority DataAccessError::_priority = 12;
160FaultStat DataAccessError::_count;
114template<> SparcFaultBase::FaultVals
115 SparcFault<DataAccessError>::vals = {"data_error", 0x032, 12};
161
116
162FaultName DataAccessProtection::_name = "data_protection";
163TrapType DataAccessProtection::_trapType = 0x033;
164FaultPriority DataAccessProtection::_priority = 12;
165FaultStat DataAccessProtection::_count;
117template<> SparcFaultBase::FaultVals
118 SparcFault<DataAccessProtection>::vals = {"data_protection", 0x033, 12};
166
119
167FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf";
168TrapType LDDFMemAddressNotAligned::_trapType = 0x035;
169FaultPriority LDDFMemAddressNotAligned::_priority = 10;
170FaultStat LDDFMemAddressNotAligned::_count;
120template<> SparcFaultBase::FaultVals
121 SparcFault<LDDFMemAddressNotAligned>::vals = {"unalign_lddf", 0x035, 10};
171
122
172FaultName STDFMemAddressNotAligned::_name = "unalign_stdf";
173TrapType STDFMemAddressNotAligned::_trapType = 0x036;
174FaultPriority STDFMemAddressNotAligned::_priority = 10;
175FaultStat STDFMemAddressNotAligned::_count;
123template<> SparcFaultBase::FaultVals
124 SparcFault<STDFMemAddressNotAligned>::vals = {"unalign_stdf", 0x036, 10};
176
125
177FaultName PrivilegedAction::_name = "priv_action";
178TrapType PrivilegedAction::_trapType = 0x037;
179FaultPriority PrivilegedAction::_priority = 11;
180FaultStat PrivilegedAction::_count;
126template<> SparcFaultBase::FaultVals
127 SparcFault<PrivilegedAction>::vals = {"priv_action", 0x037, 11};
181
128
182FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
183TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
184FaultPriority LDQFMemAddressNotAligned::_priority = 10;
185FaultStat LDQFMemAddressNotAligned::_count;
129template<> SparcFaultBase::FaultVals
130 SparcFault<LDQFMemAddressNotAligned>::vals = {"unalign_ldqf", 0x038, 10};
186
131
187FaultName STQFMemAddressNotAligned::_name = "unalign_stqf";
188TrapType STQFMemAddressNotAligned::_trapType = 0x039;
189FaultPriority STQFMemAddressNotAligned::_priority = 10;
190FaultStat STQFMemAddressNotAligned::_count;
132template<> SparcFaultBase::FaultVals
133 SparcFault<STQFMemAddressNotAligned>::vals = {"unalign_stqf", 0x039, 10};
191
134
192FaultName AsyncDataError::_name = "async_data";
193TrapType AsyncDataError::_trapType = 0x040;
194FaultPriority AsyncDataError::_priority = 2;
195FaultStat AsyncDataError::_count;
135template<> SparcFaultBase::FaultVals
136 SparcFault<AsyncDataError>::vals = {"async_data", 0x040, 2};
196
137
197FaultName CleanWindow::_name = "clean_win";
198TrapType CleanWindow::_trapType = 0x024;
199FaultPriority CleanWindow::_priority = 10;
200FaultStat CleanWindow::_count;
138template<> SparcFaultBase::FaultVals
139 SparcFault<CleanWindow>::vals = {"clean_win", 0x024, 10};
201
202//The enumerated faults
203
140
141//The enumerated faults
142
204FaultName InterruptLevelN::_name = "interrupt_n";
205TrapType InterruptLevelN::_baseTrapType = 0x041;
206FaultStat InterruptLevelN::_count;
143template<> SparcFaultBase::FaultVals
144 SparcFault<InterruptLevelN>::vals = {"interrupt_n", 0x041, 0};
207
145
208FaultName SpillNNormal::_name = "spill_n_normal";
209TrapType SpillNNormal::_baseTrapType = 0x080;
210FaultPriority SpillNNormal::_priority = 9;
211FaultStat SpillNNormal::_count;
146template<> SparcFaultBase::FaultVals
147 SparcFault<SpillNNormal>::vals = {"spill_n_normal", 0x080, 9};
212
148
213FaultName SpillNOther::_name = "spill_n_other";
214TrapType SpillNOther::_baseTrapType = 0x0A0;
215FaultPriority SpillNOther::_priority = 9;
216FaultStat SpillNOther::_count;
149template<> SparcFaultBase::FaultVals
150 SparcFault<SpillNOther>::vals = {"spill_n_other", 0x0A0, 9};
217
151
218FaultName FillNNormal::_name = "fill_n_normal";
219TrapType FillNNormal::_baseTrapType = 0x0C0;
220FaultPriority FillNNormal::_priority = 9;
221FaultStat FillNNormal::_count;
152template<> SparcFaultBase::FaultVals
153 SparcFault<FillNNormal>::vals = {"fill_n_normal", 0x0C0, 9};
222
154
223FaultName FillNOther::_name = "fill_n_other";
224TrapType FillNOther::_baseTrapType = 0x0E0;
225FaultPriority FillNOther::_priority = 9;
226FaultStat FillNOther::_count;
155template<> SparcFaultBase::FaultVals
156 SparcFault<FillNOther>::vals = {"fill_n_other", 0x0E0, 9};
227
157
228FaultName TrapInstruction::_name = "trap_inst_n";
229TrapType TrapInstruction::_baseTrapType = 0x100;
230FaultPriority TrapInstruction::_priority = 16;
231FaultStat TrapInstruction::_count;
158template<> SparcFaultBase::FaultVals
159 SparcFault<TrapInstruction>::vals = {"trap_inst_n", 0x100, 16};
232
233#if !FULL_SYSTEM
160
161#if !FULL_SYSTEM
234FaultName PageTableFault::_name = "page_table_fault";
235TrapType PageTableFault::_trapType = 0x0000;
236FaultPriority PageTableFault::_priority = 0;
237FaultStat PageTableFault::_count;
162template<> SparcFaultBase::FaultVals
163 SparcFault<PageTableFault>::vals = {"page_table_fault", 0x0000, 0};
238#endif
239
240/**
241 * This sets everything up for a normal trap except for actually jumping to
242 * the handler. It will need to be expanded to include the state machine in
243 * the manual. Right now it assumes that traps will always be to the
244 * privileged level.
245 */

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

286 //set HTSTATE.hpstate to hpstate
287 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
288
289 //TT = trap type;
290 tc->setMiscReg(MISCREG_TT, tt);
291
292 //Update the global register level
293 if(1/*We're delivering the trap in priveleged mode*/)
164#endif
165
166/**
167 * This sets everything up for a normal trap except for actually jumping to
168 * the handler. It will need to be expanded to include the state machine in
169 * the manual. Right now it assumes that traps will always be to the
170 * privileged level.
171 */

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

212 //set HTSTATE.hpstate to hpstate
213 tc->setMiscReg(MISCREG_HTSTATE, HPSTATE);
214
215 //TT = trap type;
216 tc->setMiscReg(MISCREG_TT, tt);
217
218 //Update the global register level
219 if(1/*We're delivering the trap in priveleged mode*/)
294 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
220 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL));
295 else
221 else
296 tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxPGL));
222 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxPGL));
297
298 //PSTATE.mm is unchanged
299 //PSTATE.pef = whether or not an fpu is present
300 //XXX We'll say there's one present, even though there aren't
301 //implementations for a decent number of the instructions
302 PSTATE |= (1 << 4);
303 //PSTATE.am = 0
304 PSTATE &= ~(1 << 3);

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

349 {
350 CWP = (CWP + NWindows) % NWindows;
351 tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
352 }
353}
354
355#if FULL_SYSTEM
356
223
224 //PSTATE.mm is unchanged
225 //PSTATE.pef = whether or not an fpu is present
226 //XXX We'll say there's one present, even though there aren't
227 //implementations for a decent number of the instructions
228 PSTATE |= (1 << 4);
229 //PSTATE.am = 0
230 PSTATE &= ~(1 << 3);

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

275 {
276 CWP = (CWP + NWindows) % NWindows;
277 tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
278 }
279}
280
281#if FULL_SYSTEM
282
357void SparcFault::invoke(ThreadContext * tc)
283void SparcFaultBase::invoke(ThreadContext * tc)
358{
359 FaultBase::invoke(tc);
360 countStat()++;
361
362 //Use the SPARC trap state machine
284{
285 FaultBase::invoke(tc);
286 countStat()++;
287
288 //Use the SPARC trap state machine
363}
289 /*// exception restart address
290 if (setRestartAddress() || !tc->inPalMode())
291 tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc);
364
292
365void PowerOnReset::invoke(ThreadContext * tc)
366{
367 //For SPARC, when a system is first started, there is a power
368 //on reset Trap which sets the processor into the following state.
369 //Bits that aren't set aren't defined on startup.
370 /*
371 tl = MaxTL;
372 gl = MaxGL;
293 if (skipFaultingInstruction()) {
294 // traps... skip faulting instruction.
295 tc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
296 tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
297 }
373
298
374 tickFields.counter = 0; //The TICK register is unreadable bya
375 tickFields.npt = 1; //The TICK register is unreadable by by !priv
299 if (!tc->inPalMode())
300 AlphaISA::swap_palshadow(&(tc->regs), true);
376
301
377 softint = 0; // Clear all the soft interrupt bits
378 tick_cmprFields.int_dis = 1; // disable timer compare interrupts
379 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
380 stickFields.npt = 1; //The TICK register is unreadable by by !priv
381 stick_cmprFields.int_dis = 1; // disable timer compare interrupts
382 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
383
384 tt[tl] = _trapType;
385 pstate = 0; // fields 0 but pef
386 pstateFields.pef = 1;
387
388 hpstate = 0;
389 hpstateFields.red = 1;
390 hpstateFields.hpriv = 1;
391 hpstateFields.tlz = 0; // this is a guess
392 hintp = 0; // no interrupts pending
393 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
394 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
395 */
302 tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect();
303 tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/
396}
397
398#endif
399
400#if !FULL_SYSTEM
401
304}
305
306#endif
307
308#if !FULL_SYSTEM
309
310void TrapInstruction::invoke(ThreadContext * tc)
311{
312 // Should be handled in ISA.
313}
314
402void SpillNNormal::invoke(ThreadContext *tc)
403{
404 doNormalFault(tc, trapType());
405
406 Process *p = tc->getProcessPtr();
407
408 //This will only work in faults from a SparcLiveProcess
409 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);

--- 50 unchanged lines hidden ---
315void SpillNNormal::invoke(ThreadContext *tc)
316{
317 doNormalFault(tc, trapType());
318
319 Process *p = tc->getProcessPtr();
320
321 //This will only work in faults from a SparcLiveProcess
322 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);

--- 50 unchanged lines hidden ---