Merge ktlim@zizzer:/bk/newmem
[gem5.git] / src / arch / sparc / faults.cc
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 "arch/sparc/faults.hh"
33 #include "cpu/thread_context.hh"
34 #include "cpu/base.hh"
35 #include "base/trace.hh"
36 #if !FULL_SYSTEM
37 #include "sim/process.hh"
38 #include "mem/page_table.hh"
39 #endif
40
41 namespace SparcISA
42 {
43
44 FaultName InternalProcessorError::_name = "intprocerr";
45 TrapType InternalProcessorError::_trapType = 0x029;
46 FaultPriority InternalProcessorError::_priority = 4;
47 FaultStat InternalProcessorError::_count;
48
49 FaultName MemAddressNotAligned::_name = "unalign";
50 TrapType MemAddressNotAligned::_trapType = 0x034;
51 FaultPriority MemAddressNotAligned::_priority = 10;
52 FaultStat MemAddressNotAligned::_count;
53
54 FaultName PowerOnReset::_name = "pow_reset";
55 TrapType PowerOnReset::_trapType = 0x001;
56 FaultPriority PowerOnReset::_priority = 0;
57 FaultStat PowerOnReset::_count;
58
59 FaultName WatchDogReset::_name = "watch_dog_reset";
60 TrapType WatchDogReset::_trapType = 0x002;
61 FaultPriority WatchDogReset::_priority = 1;
62 FaultStat WatchDogReset::_count;
63
64 FaultName ExternallyInitiatedReset::_name = "extern_reset";
65 TrapType ExternallyInitiatedReset::_trapType = 0x003;
66 FaultPriority ExternallyInitiatedReset::_priority = 1;
67 FaultStat ExternallyInitiatedReset::_count;
68
69 FaultName SoftwareInitiatedReset::_name = "software_reset";
70 TrapType SoftwareInitiatedReset::_trapType = 0x004;
71 FaultPriority SoftwareInitiatedReset::_priority = 1;
72 FaultStat SoftwareInitiatedReset::_count;
73
74 FaultName REDStateException::_name = "red_counte";
75 TrapType REDStateException::_trapType = 0x005;
76 FaultPriority REDStateException::_priority = 1;
77 FaultStat REDStateException::_count;
78
79 FaultName InstructionAccessException::_name = "inst_access";
80 TrapType InstructionAccessException::_trapType = 0x008;
81 FaultPriority InstructionAccessException::_priority = 5;
82 FaultStat InstructionAccessException::_count;
83
84 FaultName InstructionAccessMMUMiss::_name = "inst_mmu";
85 TrapType InstructionAccessMMUMiss::_trapType = 0x009;
86 FaultPriority InstructionAccessMMUMiss::_priority = 2;
87 FaultStat InstructionAccessMMUMiss::_count;
88
89 FaultName InstructionAccessError::_name = "inst_error";
90 TrapType InstructionAccessError::_trapType = 0x00A;
91 FaultPriority InstructionAccessError::_priority = 3;
92 FaultStat InstructionAccessError::_count;
93
94 FaultName IllegalInstruction::_name = "illegal_inst";
95 TrapType IllegalInstruction::_trapType = 0x010;
96 FaultPriority IllegalInstruction::_priority = 7;
97 FaultStat IllegalInstruction::_count;
98
99 FaultName PrivilegedOpcode::_name = "priv_opcode";
100 TrapType PrivilegedOpcode::_trapType = 0x011;
101 FaultPriority PrivilegedOpcode::_priority = 6;
102 FaultStat PrivilegedOpcode::_count;
103
104 FaultName UnimplementedLDD::_name = "unimp_ldd";
105 TrapType UnimplementedLDD::_trapType = 0x012;
106 FaultPriority UnimplementedLDD::_priority = 6;
107 FaultStat UnimplementedLDD::_count;
108
109 FaultName UnimplementedSTD::_name = "unimp_std";
110 TrapType UnimplementedSTD::_trapType = 0x013;
111 FaultPriority UnimplementedSTD::_priority = 6;
112 FaultStat UnimplementedSTD::_count;
113
114 FaultName FpDisabled::_name = "fp_disabled";
115 TrapType FpDisabled::_trapType = 0x020;
116 FaultPriority FpDisabled::_priority = 8;
117 FaultStat FpDisabled::_count;
118
119 FaultName FpExceptionIEEE754::_name = "fp_754";
120 TrapType FpExceptionIEEE754::_trapType = 0x021;
121 FaultPriority FpExceptionIEEE754::_priority = 11;
122 FaultStat FpExceptionIEEE754::_count;
123
124 FaultName FpExceptionOther::_name = "fp_other";
125 TrapType FpExceptionOther::_trapType = 0x022;
126 FaultPriority FpExceptionOther::_priority = 11;
127 FaultStat FpExceptionOther::_count;
128
129 FaultName TagOverflow::_name = "tag_overflow";
130 TrapType TagOverflow::_trapType = 0x023;
131 FaultPriority TagOverflow::_priority = 14;
132 FaultStat TagOverflow::_count;
133
134 FaultName DivisionByZero::_name = "div_by_zero";
135 TrapType DivisionByZero::_trapType = 0x028;
136 FaultPriority DivisionByZero::_priority = 15;
137 FaultStat DivisionByZero::_count;
138
139 FaultName DataAccessException::_name = "data_access";
140 TrapType DataAccessException::_trapType = 0x030;
141 FaultPriority DataAccessException::_priority = 12;
142 FaultStat DataAccessException::_count;
143
144 FaultName DataAccessMMUMiss::_name = "data_mmu";
145 TrapType DataAccessMMUMiss::_trapType = 0x031;
146 FaultPriority DataAccessMMUMiss::_priority = 12;
147 FaultStat DataAccessMMUMiss::_count;
148
149 FaultName DataAccessError::_name = "data_error";
150 TrapType DataAccessError::_trapType = 0x032;
151 FaultPriority DataAccessError::_priority = 12;
152 FaultStat DataAccessError::_count;
153
154 FaultName DataAccessProtection::_name = "data_protection";
155 TrapType DataAccessProtection::_trapType = 0x033;
156 FaultPriority DataAccessProtection::_priority = 12;
157 FaultStat DataAccessProtection::_count;
158
159 FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf";
160 TrapType LDDFMemAddressNotAligned::_trapType = 0x035;
161 FaultPriority LDDFMemAddressNotAligned::_priority = 10;
162 FaultStat LDDFMemAddressNotAligned::_count;
163
164 FaultName STDFMemAddressNotAligned::_name = "unalign_stdf";
165 TrapType STDFMemAddressNotAligned::_trapType = 0x036;
166 FaultPriority STDFMemAddressNotAligned::_priority = 10;
167 FaultStat STDFMemAddressNotAligned::_count;
168
169 FaultName PrivilegedAction::_name = "priv_action";
170 TrapType PrivilegedAction::_trapType = 0x037;
171 FaultPriority PrivilegedAction::_priority = 11;
172 FaultStat PrivilegedAction::_count;
173
174 FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
175 TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
176 FaultPriority LDQFMemAddressNotAligned::_priority = 10;
177 FaultStat LDQFMemAddressNotAligned::_count;
178
179 FaultName STQFMemAddressNotAligned::_name = "unalign_stqf";
180 TrapType STQFMemAddressNotAligned::_trapType = 0x039;
181 FaultPriority STQFMemAddressNotAligned::_priority = 10;
182 FaultStat STQFMemAddressNotAligned::_count;
183
184 FaultName AsyncDataError::_name = "async_data";
185 TrapType AsyncDataError::_trapType = 0x040;
186 FaultPriority AsyncDataError::_priority = 2;
187 FaultStat AsyncDataError::_count;
188
189 FaultName CleanWindow::_name = "clean_win";
190 TrapType CleanWindow::_trapType = 0x024;
191 FaultPriority CleanWindow::_priority = 10;
192 FaultStat CleanWindow::_count;
193
194 //The enumerated faults
195
196 FaultName InterruptLevelN::_name = "interrupt_n";
197 TrapType InterruptLevelN::_baseTrapType = 0x041;
198 FaultStat InterruptLevelN::_count;
199
200 FaultName SpillNNormal::_name = "spill_n_normal";
201 TrapType SpillNNormal::_baseTrapType = 0x080;
202 FaultPriority SpillNNormal::_priority = 9;
203 FaultStat SpillNNormal::_count;
204
205 FaultName SpillNOther::_name = "spill_n_other";
206 TrapType SpillNOther::_baseTrapType = 0x0A0;
207 FaultPriority SpillNOther::_priority = 9;
208 FaultStat SpillNOther::_count;
209
210 FaultName FillNNormal::_name = "fill_n_normal";
211 TrapType FillNNormal::_baseTrapType = 0x0C0;
212 FaultPriority FillNNormal::_priority = 9;
213 FaultStat FillNNormal::_count;
214
215 FaultName FillNOther::_name = "fill_n_other";
216 TrapType FillNOther::_baseTrapType = 0x0E0;
217 FaultPriority FillNOther::_priority = 9;
218 FaultStat FillNOther::_count;
219
220 FaultName TrapInstruction::_name = "trap_inst_n";
221 TrapType TrapInstruction::_baseTrapType = 0x100;
222 FaultPriority TrapInstruction::_priority = 16;
223 FaultStat TrapInstruction::_count;
224
225 #if !FULL_SYSTEM
226 FaultName PageTableFault::_name = "page_table_fault";
227 TrapType PageTableFault::_trapType = 0x0000;
228 FaultPriority PageTableFault::_priority = 0;
229 FaultStat PageTableFault::_count;
230 #endif
231
232 #if FULL_SYSTEM
233
234 void SparcFault::invoke(ThreadContext * tc)
235 {
236 FaultBase::invoke(tc);
237 countStat()++;
238
239 //Use the SPARC trap state machine
240 /*// exception restart address
241 if (setRestartAddress() || !tc->inPalMode())
242 tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc);
243
244 if (skipFaultingInstruction()) {
245 // traps... skip faulting instruction.
246 tc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
247 tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
248 }
249
250 if (!tc->inPalMode())
251 AlphaISA::swap_palshadow(&(tc->regs), true);
252
253 tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect();
254 tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/
255 }
256
257 #endif
258
259 #if !FULL_SYSTEM
260
261 void TrapInstruction::invoke(ThreadContext * tc)
262 {
263 // Should be handled in ISA.
264 }
265
266 void 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 }
285 #endif
286
287 } // namespace SparcISA
288