faults.cc (3523:f145bc050815) faults.cc (3531:51eb743f38f5)
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;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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 "base/bitfield.hh"
37#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
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
52FaultName InternalProcessorError::_name = "intprocerr";
53TrapType InternalProcessorError::_trapType = 0x029;
54FaultPriority InternalProcessorError::_priority = 4;
55FaultStat InternalProcessorError::_count;
56
57FaultName MemAddressNotAligned::_name = "unalign";
58TrapType MemAddressNotAligned::_trapType = 0x034;
59FaultPriority MemAddressNotAligned::_priority = 10;
60FaultStat MemAddressNotAligned::_count;
61
62FaultName PowerOnReset::_name = "pow_reset";
63TrapType PowerOnReset::_trapType = 0x001;
64FaultPriority PowerOnReset::_priority = 0;
65FaultStat PowerOnReset::_count;
66
67FaultName WatchDogReset::_name = "watch_dog_reset";
68TrapType WatchDogReset::_trapType = 0x002;
69FaultPriority WatchDogReset::_priority = 1;
70FaultStat WatchDogReset::_count;
71
72FaultName ExternallyInitiatedReset::_name = "extern_reset";
73TrapType ExternallyInitiatedReset::_trapType = 0x003;
74FaultPriority ExternallyInitiatedReset::_priority = 1;
75FaultStat ExternallyInitiatedReset::_count;
76
77FaultName SoftwareInitiatedReset::_name = "software_reset";
78TrapType SoftwareInitiatedReset::_trapType = 0x004;
79FaultPriority SoftwareInitiatedReset::_priority = 1;
80FaultStat SoftwareInitiatedReset::_count;
81
82FaultName REDStateException::_name = "red_counte";
83TrapType REDStateException::_trapType = 0x005;
84FaultPriority REDStateException::_priority = 1;
85FaultStat REDStateException::_count;
86
87FaultName InstructionAccessException::_name = "inst_access";
88TrapType InstructionAccessException::_trapType = 0x008;
89FaultPriority InstructionAccessException::_priority = 5;
90FaultStat InstructionAccessException::_count;
91
92FaultName InstructionAccessMMUMiss::_name = "inst_mmu";
93TrapType InstructionAccessMMUMiss::_trapType = 0x009;
94FaultPriority InstructionAccessMMUMiss::_priority = 2;
95FaultStat InstructionAccessMMUMiss::_count;
96
97FaultName InstructionAccessError::_name = "inst_error";
98TrapType InstructionAccessError::_trapType = 0x00A;
99FaultPriority InstructionAccessError::_priority = 3;
100FaultStat InstructionAccessError::_count;
101
102FaultName IllegalInstruction::_name = "illegal_inst";
103TrapType IllegalInstruction::_trapType = 0x010;
104FaultPriority IllegalInstruction::_priority = 7;
105FaultStat IllegalInstruction::_count;
106
107FaultName PrivilegedOpcode::_name = "priv_opcode";
108TrapType PrivilegedOpcode::_trapType = 0x011;
109FaultPriority PrivilegedOpcode::_priority = 6;
110FaultStat PrivilegedOpcode::_count;
111
112FaultName UnimplementedLDD::_name = "unimp_ldd";
113TrapType UnimplementedLDD::_trapType = 0x012;
114FaultPriority UnimplementedLDD::_priority = 6;
115FaultStat UnimplementedLDD::_count;
116
117FaultName UnimplementedSTD::_name = "unimp_std";
118TrapType UnimplementedSTD::_trapType = 0x013;
119FaultPriority UnimplementedSTD::_priority = 6;
120FaultStat UnimplementedSTD::_count;
121
122FaultName FpDisabled::_name = "fp_disabled";
123TrapType FpDisabled::_trapType = 0x020;
124FaultPriority FpDisabled::_priority = 8;
125FaultStat FpDisabled::_count;
126
127FaultName FpExceptionIEEE754::_name = "fp_754";
128TrapType FpExceptionIEEE754::_trapType = 0x021;
129FaultPriority FpExceptionIEEE754::_priority = 11;
130FaultStat FpExceptionIEEE754::_count;
131
132FaultName FpExceptionOther::_name = "fp_other";
133TrapType FpExceptionOther::_trapType = 0x022;
134FaultPriority FpExceptionOther::_priority = 11;
135FaultStat FpExceptionOther::_count;
136
137FaultName TagOverflow::_name = "tag_overflow";
138TrapType TagOverflow::_trapType = 0x023;
139FaultPriority TagOverflow::_priority = 14;
140FaultStat TagOverflow::_count;
141
142FaultName DivisionByZero::_name = "div_by_zero";
143TrapType DivisionByZero::_trapType = 0x028;
144FaultPriority DivisionByZero::_priority = 15;
145FaultStat DivisionByZero::_count;
146
147FaultName DataAccessException::_name = "data_access";
148TrapType DataAccessException::_trapType = 0x030;
149FaultPriority DataAccessException::_priority = 12;
150FaultStat DataAccessException::_count;
151
152FaultName DataAccessMMUMiss::_name = "data_mmu";
153TrapType DataAccessMMUMiss::_trapType = 0x031;
154FaultPriority DataAccessMMUMiss::_priority = 12;
155FaultStat DataAccessMMUMiss::_count;
156
157FaultName DataAccessError::_name = "data_error";
158TrapType DataAccessError::_trapType = 0x032;
159FaultPriority DataAccessError::_priority = 12;
160FaultStat DataAccessError::_count;
161
162FaultName DataAccessProtection::_name = "data_protection";
163TrapType DataAccessProtection::_trapType = 0x033;
164FaultPriority DataAccessProtection::_priority = 12;
165FaultStat DataAccessProtection::_count;
166
167FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf";
168TrapType LDDFMemAddressNotAligned::_trapType = 0x035;
169FaultPriority LDDFMemAddressNotAligned::_priority = 10;
170FaultStat LDDFMemAddressNotAligned::_count;
171
172FaultName STDFMemAddressNotAligned::_name = "unalign_stdf";
173TrapType STDFMemAddressNotAligned::_trapType = 0x036;
174FaultPriority STDFMemAddressNotAligned::_priority = 10;
175FaultStat STDFMemAddressNotAligned::_count;
176
177FaultName PrivilegedAction::_name = "priv_action";
178TrapType PrivilegedAction::_trapType = 0x037;
179FaultPriority PrivilegedAction::_priority = 11;
180FaultStat PrivilegedAction::_count;
181
182FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
183TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
184FaultPriority LDQFMemAddressNotAligned::_priority = 10;
185FaultStat LDQFMemAddressNotAligned::_count;
186
187FaultName STQFMemAddressNotAligned::_name = "unalign_stqf";
188TrapType STQFMemAddressNotAligned::_trapType = 0x039;
189FaultPriority STQFMemAddressNotAligned::_priority = 10;
190FaultStat STQFMemAddressNotAligned::_count;
191
192FaultName AsyncDataError::_name = "async_data";
193TrapType AsyncDataError::_trapType = 0x040;
194FaultPriority AsyncDataError::_priority = 2;
195FaultStat AsyncDataError::_count;
196
197FaultName CleanWindow::_name = "clean_win";
198TrapType CleanWindow::_trapType = 0x024;
199FaultPriority CleanWindow::_priority = 10;
200FaultStat CleanWindow::_count;
201
202//The enumerated faults
203
204FaultName InterruptLevelN::_name = "interrupt_n";
205TrapType InterruptLevelN::_baseTrapType = 0x041;
206FaultStat InterruptLevelN::_count;
207
208FaultName SpillNNormal::_name = "spill_n_normal";
209TrapType SpillNNormal::_baseTrapType = 0x080;
210FaultPriority SpillNNormal::_priority = 9;
211FaultStat SpillNNormal::_count;
212
213FaultName SpillNOther::_name = "spill_n_other";
214TrapType SpillNOther::_baseTrapType = 0x0A0;
215FaultPriority SpillNOther::_priority = 9;
216FaultStat SpillNOther::_count;
217
218FaultName FillNNormal::_name = "fill_n_normal";
219TrapType FillNNormal::_baseTrapType = 0x0C0;
220FaultPriority FillNNormal::_priority = 9;
221FaultStat FillNNormal::_count;
222
223FaultName FillNOther::_name = "fill_n_other";
224TrapType FillNOther::_baseTrapType = 0x0E0;
225FaultPriority FillNOther::_priority = 9;
226FaultStat FillNOther::_count;
227
228FaultName TrapInstruction::_name = "trap_inst_n";
229TrapType TrapInstruction::_baseTrapType = 0x100;
230FaultPriority TrapInstruction::_priority = 16;
231FaultStat TrapInstruction::_count;
232
233#if !FULL_SYSTEM
234FaultName PageTableFault::_name = "page_table_fault";
235TrapType PageTableFault::_trapType = 0x0000;
236FaultPriority PageTableFault::_priority = 0;
237FaultStat PageTableFault::_count;
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 */
246
247void doNormalFault(ThreadContext *tc, TrapType tt)
248{
249 uint64_t TL = tc->readMiscReg(MISCREG_TL);
250 uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE);
251 uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE);
252 uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
253 uint64_t CCR = tc->readMiscReg(MISCREG_CCR);
254 uint64_t ASI = tc->readMiscReg(MISCREG_ASI);
255 uint64_t CWP = tc->readMiscReg(MISCREG_CWP);
256 uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
257 uint64_t GL = tc->readMiscReg(MISCREG_GL);
258 uint64_t PC = tc->readPC();
259 uint64_t NPC = tc->readNextPC();
260
261 //Increment the trap level
262 TL++;
263 tc->setMiscReg(MISCREG_TL, TL);
264
265 //Save off state
266
267 //set TSTATE.gl to gl
268 replaceBits(TSTATE, 42, 40, GL);
269 //set TSTATE.ccr to ccr
270 replaceBits(TSTATE, 39, 32, CCR);
271 //set TSTATE.asi to asi
272 replaceBits(TSTATE, 31, 24, ASI);
273 //set TSTATE.pstate to pstate
274 replaceBits(TSTATE, 20, 8, PSTATE);
275 //set TSTATE.cwp to cwp
276 replaceBits(TSTATE, 4, 0, CWP);
277
278 //Write back TSTATE
279 tc->setMiscReg(MISCREG_TSTATE, TSTATE);
280
281 //set TPC to PC
282 tc->setMiscReg(MISCREG_TPC, PC);
283 //set TNPC to NPC
284 tc->setMiscReg(MISCREG_TNPC, NPC);
285
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*/)
294 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL));
295 else
296 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);
305 if(1/*We're delivering the trap in priveleged mode*/)
306 {
307 //PSTATE.priv = 1
308 PSTATE |= (1 << 2);
309 //PSTATE.cle = PSTATE.tle
310 replaceBits(PSTATE, 9, 9, PSTATE >> 8);
311 }
312 else
313 {
314 //PSTATE.priv = 0
315 PSTATE &= ~(1 << 2);
316 //PSTATE.cle = 0
317 PSTATE &= ~(1 << 9);
318 }
319 //PSTATE.ie = 0
320 PSTATE &= ~(1 << 1);
321 //PSTATE.tle is unchanged
322 //PSTATE.tct = 0
323 //XXX Where exactly is this field?
324 tc->setMiscReg(MISCREG_PSTATE, PSTATE);
325
326 if(0/*We're delivering the trap in hyperprivileged mode*/)
327 {
328 //HPSTATE.red = 0
329 HPSTATE &= ~(1 << 5);
330 //HPSTATE.hpriv = 1
331 HPSTATE |= (1 << 2);
332 //HPSTATE.ibe = 0
333 HPSTATE &= ~(1 << 10);
334 //HPSTATE.tlz is unchanged
335 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
336 }
337
338 bool changedCWP = true;
339 if(tt == 0x24)
340 CWP++;
341 else if(0x80 <= tt && tt <= 0xbf)
342 CWP += (CANSAVE + 2);
343 else if(0xc0 <= tt && tt <= 0xff)
344 CWP--;
345 else
346 changedCWP = false;
347
348 if(changedCWP)
349 {
350 CWP = (CWP + NWindows) % NWindows;
351 tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
352 }
353}
354
355#if FULL_SYSTEM
356
357void SparcFault::invoke(ThreadContext * tc)
358{
359 FaultBase::invoke(tc);
360 countStat()++;
361
362 //Use the SPARC trap state machine
363}
364
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;
373
374 tickFields.counter = 0; //The TICK register is unreadable bya
375 tickFields.npt = 1; //The TICK register is unreadable by by !priv
376
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 */
396}
397
398#endif
399
400#if !FULL_SYSTEM
401
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;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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 "base/bitfield.hh"
37#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
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
52FaultName InternalProcessorError::_name = "intprocerr";
53TrapType InternalProcessorError::_trapType = 0x029;
54FaultPriority InternalProcessorError::_priority = 4;
55FaultStat InternalProcessorError::_count;
56
57FaultName MemAddressNotAligned::_name = "unalign";
58TrapType MemAddressNotAligned::_trapType = 0x034;
59FaultPriority MemAddressNotAligned::_priority = 10;
60FaultStat MemAddressNotAligned::_count;
61
62FaultName PowerOnReset::_name = "pow_reset";
63TrapType PowerOnReset::_trapType = 0x001;
64FaultPriority PowerOnReset::_priority = 0;
65FaultStat PowerOnReset::_count;
66
67FaultName WatchDogReset::_name = "watch_dog_reset";
68TrapType WatchDogReset::_trapType = 0x002;
69FaultPriority WatchDogReset::_priority = 1;
70FaultStat WatchDogReset::_count;
71
72FaultName ExternallyInitiatedReset::_name = "extern_reset";
73TrapType ExternallyInitiatedReset::_trapType = 0x003;
74FaultPriority ExternallyInitiatedReset::_priority = 1;
75FaultStat ExternallyInitiatedReset::_count;
76
77FaultName SoftwareInitiatedReset::_name = "software_reset";
78TrapType SoftwareInitiatedReset::_trapType = 0x004;
79FaultPriority SoftwareInitiatedReset::_priority = 1;
80FaultStat SoftwareInitiatedReset::_count;
81
82FaultName REDStateException::_name = "red_counte";
83TrapType REDStateException::_trapType = 0x005;
84FaultPriority REDStateException::_priority = 1;
85FaultStat REDStateException::_count;
86
87FaultName InstructionAccessException::_name = "inst_access";
88TrapType InstructionAccessException::_trapType = 0x008;
89FaultPriority InstructionAccessException::_priority = 5;
90FaultStat InstructionAccessException::_count;
91
92FaultName InstructionAccessMMUMiss::_name = "inst_mmu";
93TrapType InstructionAccessMMUMiss::_trapType = 0x009;
94FaultPriority InstructionAccessMMUMiss::_priority = 2;
95FaultStat InstructionAccessMMUMiss::_count;
96
97FaultName InstructionAccessError::_name = "inst_error";
98TrapType InstructionAccessError::_trapType = 0x00A;
99FaultPriority InstructionAccessError::_priority = 3;
100FaultStat InstructionAccessError::_count;
101
102FaultName IllegalInstruction::_name = "illegal_inst";
103TrapType IllegalInstruction::_trapType = 0x010;
104FaultPriority IllegalInstruction::_priority = 7;
105FaultStat IllegalInstruction::_count;
106
107FaultName PrivilegedOpcode::_name = "priv_opcode";
108TrapType PrivilegedOpcode::_trapType = 0x011;
109FaultPriority PrivilegedOpcode::_priority = 6;
110FaultStat PrivilegedOpcode::_count;
111
112FaultName UnimplementedLDD::_name = "unimp_ldd";
113TrapType UnimplementedLDD::_trapType = 0x012;
114FaultPriority UnimplementedLDD::_priority = 6;
115FaultStat UnimplementedLDD::_count;
116
117FaultName UnimplementedSTD::_name = "unimp_std";
118TrapType UnimplementedSTD::_trapType = 0x013;
119FaultPriority UnimplementedSTD::_priority = 6;
120FaultStat UnimplementedSTD::_count;
121
122FaultName FpDisabled::_name = "fp_disabled";
123TrapType FpDisabled::_trapType = 0x020;
124FaultPriority FpDisabled::_priority = 8;
125FaultStat FpDisabled::_count;
126
127FaultName FpExceptionIEEE754::_name = "fp_754";
128TrapType FpExceptionIEEE754::_trapType = 0x021;
129FaultPriority FpExceptionIEEE754::_priority = 11;
130FaultStat FpExceptionIEEE754::_count;
131
132FaultName FpExceptionOther::_name = "fp_other";
133TrapType FpExceptionOther::_trapType = 0x022;
134FaultPriority FpExceptionOther::_priority = 11;
135FaultStat FpExceptionOther::_count;
136
137FaultName TagOverflow::_name = "tag_overflow";
138TrapType TagOverflow::_trapType = 0x023;
139FaultPriority TagOverflow::_priority = 14;
140FaultStat TagOverflow::_count;
141
142FaultName DivisionByZero::_name = "div_by_zero";
143TrapType DivisionByZero::_trapType = 0x028;
144FaultPriority DivisionByZero::_priority = 15;
145FaultStat DivisionByZero::_count;
146
147FaultName DataAccessException::_name = "data_access";
148TrapType DataAccessException::_trapType = 0x030;
149FaultPriority DataAccessException::_priority = 12;
150FaultStat DataAccessException::_count;
151
152FaultName DataAccessMMUMiss::_name = "data_mmu";
153TrapType DataAccessMMUMiss::_trapType = 0x031;
154FaultPriority DataAccessMMUMiss::_priority = 12;
155FaultStat DataAccessMMUMiss::_count;
156
157FaultName DataAccessError::_name = "data_error";
158TrapType DataAccessError::_trapType = 0x032;
159FaultPriority DataAccessError::_priority = 12;
160FaultStat DataAccessError::_count;
161
162FaultName DataAccessProtection::_name = "data_protection";
163TrapType DataAccessProtection::_trapType = 0x033;
164FaultPriority DataAccessProtection::_priority = 12;
165FaultStat DataAccessProtection::_count;
166
167FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf";
168TrapType LDDFMemAddressNotAligned::_trapType = 0x035;
169FaultPriority LDDFMemAddressNotAligned::_priority = 10;
170FaultStat LDDFMemAddressNotAligned::_count;
171
172FaultName STDFMemAddressNotAligned::_name = "unalign_stdf";
173TrapType STDFMemAddressNotAligned::_trapType = 0x036;
174FaultPriority STDFMemAddressNotAligned::_priority = 10;
175FaultStat STDFMemAddressNotAligned::_count;
176
177FaultName PrivilegedAction::_name = "priv_action";
178TrapType PrivilegedAction::_trapType = 0x037;
179FaultPriority PrivilegedAction::_priority = 11;
180FaultStat PrivilegedAction::_count;
181
182FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
183TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
184FaultPriority LDQFMemAddressNotAligned::_priority = 10;
185FaultStat LDQFMemAddressNotAligned::_count;
186
187FaultName STQFMemAddressNotAligned::_name = "unalign_stqf";
188TrapType STQFMemAddressNotAligned::_trapType = 0x039;
189FaultPriority STQFMemAddressNotAligned::_priority = 10;
190FaultStat STQFMemAddressNotAligned::_count;
191
192FaultName AsyncDataError::_name = "async_data";
193TrapType AsyncDataError::_trapType = 0x040;
194FaultPriority AsyncDataError::_priority = 2;
195FaultStat AsyncDataError::_count;
196
197FaultName CleanWindow::_name = "clean_win";
198TrapType CleanWindow::_trapType = 0x024;
199FaultPriority CleanWindow::_priority = 10;
200FaultStat CleanWindow::_count;
201
202//The enumerated faults
203
204FaultName InterruptLevelN::_name = "interrupt_n";
205TrapType InterruptLevelN::_baseTrapType = 0x041;
206FaultStat InterruptLevelN::_count;
207
208FaultName SpillNNormal::_name = "spill_n_normal";
209TrapType SpillNNormal::_baseTrapType = 0x080;
210FaultPriority SpillNNormal::_priority = 9;
211FaultStat SpillNNormal::_count;
212
213FaultName SpillNOther::_name = "spill_n_other";
214TrapType SpillNOther::_baseTrapType = 0x0A0;
215FaultPriority SpillNOther::_priority = 9;
216FaultStat SpillNOther::_count;
217
218FaultName FillNNormal::_name = "fill_n_normal";
219TrapType FillNNormal::_baseTrapType = 0x0C0;
220FaultPriority FillNNormal::_priority = 9;
221FaultStat FillNNormal::_count;
222
223FaultName FillNOther::_name = "fill_n_other";
224TrapType FillNOther::_baseTrapType = 0x0E0;
225FaultPriority FillNOther::_priority = 9;
226FaultStat FillNOther::_count;
227
228FaultName TrapInstruction::_name = "trap_inst_n";
229TrapType TrapInstruction::_baseTrapType = 0x100;
230FaultPriority TrapInstruction::_priority = 16;
231FaultStat TrapInstruction::_count;
232
233#if !FULL_SYSTEM
234FaultName PageTableFault::_name = "page_table_fault";
235TrapType PageTableFault::_trapType = 0x0000;
236FaultPriority PageTableFault::_priority = 0;
237FaultStat PageTableFault::_count;
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 */
246
247void doNormalFault(ThreadContext *tc, TrapType tt)
248{
249 uint64_t TL = tc->readMiscReg(MISCREG_TL);
250 uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE);
251 uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE);
252 uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
253 uint64_t CCR = tc->readMiscReg(MISCREG_CCR);
254 uint64_t ASI = tc->readMiscReg(MISCREG_ASI);
255 uint64_t CWP = tc->readMiscReg(MISCREG_CWP);
256 uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
257 uint64_t GL = tc->readMiscReg(MISCREG_GL);
258 uint64_t PC = tc->readPC();
259 uint64_t NPC = tc->readNextPC();
260
261 //Increment the trap level
262 TL++;
263 tc->setMiscReg(MISCREG_TL, TL);
264
265 //Save off state
266
267 //set TSTATE.gl to gl
268 replaceBits(TSTATE, 42, 40, GL);
269 //set TSTATE.ccr to ccr
270 replaceBits(TSTATE, 39, 32, CCR);
271 //set TSTATE.asi to asi
272 replaceBits(TSTATE, 31, 24, ASI);
273 //set TSTATE.pstate to pstate
274 replaceBits(TSTATE, 20, 8, PSTATE);
275 //set TSTATE.cwp to cwp
276 replaceBits(TSTATE, 4, 0, CWP);
277
278 //Write back TSTATE
279 tc->setMiscReg(MISCREG_TSTATE, TSTATE);
280
281 //set TPC to PC
282 tc->setMiscReg(MISCREG_TPC, PC);
283 //set TNPC to NPC
284 tc->setMiscReg(MISCREG_TNPC, NPC);
285
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*/)
294 tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL));
295 else
296 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);
305 if(1/*We're delivering the trap in priveleged mode*/)
306 {
307 //PSTATE.priv = 1
308 PSTATE |= (1 << 2);
309 //PSTATE.cle = PSTATE.tle
310 replaceBits(PSTATE, 9, 9, PSTATE >> 8);
311 }
312 else
313 {
314 //PSTATE.priv = 0
315 PSTATE &= ~(1 << 2);
316 //PSTATE.cle = 0
317 PSTATE &= ~(1 << 9);
318 }
319 //PSTATE.ie = 0
320 PSTATE &= ~(1 << 1);
321 //PSTATE.tle is unchanged
322 //PSTATE.tct = 0
323 //XXX Where exactly is this field?
324 tc->setMiscReg(MISCREG_PSTATE, PSTATE);
325
326 if(0/*We're delivering the trap in hyperprivileged mode*/)
327 {
328 //HPSTATE.red = 0
329 HPSTATE &= ~(1 << 5);
330 //HPSTATE.hpriv = 1
331 HPSTATE |= (1 << 2);
332 //HPSTATE.ibe = 0
333 HPSTATE &= ~(1 << 10);
334 //HPSTATE.tlz is unchanged
335 tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
336 }
337
338 bool changedCWP = true;
339 if(tt == 0x24)
340 CWP++;
341 else if(0x80 <= tt && tt <= 0xbf)
342 CWP += (CANSAVE + 2);
343 else if(0xc0 <= tt && tt <= 0xff)
344 CWP--;
345 else
346 changedCWP = false;
347
348 if(changedCWP)
349 {
350 CWP = (CWP + NWindows) % NWindows;
351 tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
352 }
353}
354
355#if FULL_SYSTEM
356
357void SparcFault::invoke(ThreadContext * tc)
358{
359 FaultBase::invoke(tc);
360 countStat()++;
361
362 //Use the SPARC trap state machine
363}
364
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;
373
374 tickFields.counter = 0; //The TICK register is unreadable bya
375 tickFields.npt = 1; //The TICK register is unreadable by by !priv
376
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 */
396}
397
398#endif
399
400#if !FULL_SYSTEM
401
402void TrapInstruction::invoke(ThreadContext * tc)
403{
404 // Should be handled in ISA.
405}
406
407void SpillNNormal::invoke(ThreadContext *tc)
408{
409 doNormalFault(tc, trapType());
410
411 Process *p = tc->getProcessPtr();
412
413 //This will only work in faults from a SparcLiveProcess
414 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
415 assert(lp);
416
417 //Then adjust the PC and NPC
418 Addr spillStart = lp->readSpillStart();
419 tc->setPC(spillStart);
420 tc->setNextPC(spillStart + sizeof(MachInst));
421 tc->setNextNPC(spillStart + 2*sizeof(MachInst));
422}
423
424void FillNNormal::invoke(ThreadContext *tc)
425{
426 doNormalFault(tc, trapType());
427
428 Process * p = tc->getProcessPtr();
429
430 //This will only work in faults from a SparcLiveProcess
431 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
432 assert(lp);
433
434 //The adjust the PC and NPC
435 Addr fillStart = lp->readFillStart();
436 tc->setPC(fillStart);
437 tc->setNextPC(fillStart + sizeof(MachInst));
438 tc->setNextNPC(fillStart + 2*sizeof(MachInst));
439}
440
441void PageTableFault::invoke(ThreadContext *tc)
442{
443 Process *p = tc->getProcessPtr();
444
445 // address is higher than the stack region or in the current stack region
446 if (vaddr > p->stack_base || vaddr > p->stack_min)
447 FaultBase::invoke(tc);
448
449 // We've accessed the next page
450 if (vaddr > p->stack_min - PageBytes) {
451 p->stack_min -= PageBytes;
452 if (p->stack_base - p->stack_min > 8*1024*1024)
453 fatal("Over max stack size for one thread\n");
454 p->pTable->allocate(p->stack_min, PageBytes);
455 warn("Increasing stack size by one page.");
456 } else {
457 FaultBase::invoke(tc);
458 }
459}
460
461#endif
462
463} // namespace SparcISA
464
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);
410 assert(lp);
411
412 //Then adjust the PC and NPC
413 Addr spillStart = lp->readSpillStart();
414 tc->setPC(spillStart);
415 tc->setNextPC(spillStart + sizeof(MachInst));
416 tc->setNextNPC(spillStart + 2*sizeof(MachInst));
417}
418
419void FillNNormal::invoke(ThreadContext *tc)
420{
421 doNormalFault(tc, trapType());
422
423 Process * p = tc->getProcessPtr();
424
425 //This will only work in faults from a SparcLiveProcess
426 SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
427 assert(lp);
428
429 //The adjust the PC and NPC
430 Addr fillStart = lp->readFillStart();
431 tc->setPC(fillStart);
432 tc->setNextPC(fillStart + sizeof(MachInst));
433 tc->setNextNPC(fillStart + 2*sizeof(MachInst));
434}
435
436void PageTableFault::invoke(ThreadContext *tc)
437{
438 Process *p = tc->getProcessPtr();
439
440 // address is higher than the stack region or in the current stack region
441 if (vaddr > p->stack_base || vaddr > p->stack_min)
442 FaultBase::invoke(tc);
443
444 // We've accessed the next page
445 if (vaddr > p->stack_min - PageBytes) {
446 p->stack_min -= PageBytes;
447 if (p->stack_base - p->stack_min > 8*1024*1024)
448 fatal("Over max stack size for one thread\n");
449 p->pTable->allocate(p->stack_min, PageBytes);
450 warn("Increasing stack size by one page.");
451 } else {
452 FaultBase::invoke(tc);
453 }
454}
455
456#endif
457
458} // namespace SparcISA
459